home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / bc_pas_1.zip / DIALOG.C < prev    next >
Text File  |  1992-11-20  |  76KB  |  3,538 lines

  1. ;    /*\
  2. ;    |*| $Author:   DCODY  $
  3. ;    |*| 
  4. ;    |*| $Date:   20 Nov 1992 16:35:26  $
  5. ;    |*| 
  6. ;    |*| $Header:   X:/sccs/mixers/dialog.c_v   1.16   20 Nov 1992 16:35:26   DCODY  $
  7. ;    |*| 
  8. ;    |*| $Log:   X:/sccs/mixers/dialog.c_v  $
  9.  * 
  10.  *    Rev 1.16   20 Nov 1992 16:35:26   DCODY
  11.  * changed the dissolve screen restore to work only on exit of the dialog. Also
  12.  * corrected a couple Borland C barfs.
  13.  * 
  14.  *    Rev 1.15   12 Nov 1992 10:02:40   DCODY
  15.  * added dissolve on screen restoration. Changed some code for
  16.  * Borland compatibility.
  17.  * 
  18.  *    Rev 1.14   20 Oct 1992 15:53:30   BCRANE
  19.  * changed text on Speaker control to include SB Volume
  20.  * 
  21.  *    Rev 1.13   19 Oct 1992 11:41:18   BCRANE
  22.  * added "blank" strings for when no SB volume control on PAS+
  23.  * 
  24.  *    Rev 1.12   16 Oct 1992 10:19:30   BCRANE
  25.  * fixed error in getting the pathname
  26.  * DOS has "C:\" for the root, whereas we store only "C:", so
  27.  * building the pathname for the settings.pas file was "C:settings.pas"
  28.  * when mvsound.sys was in the root directory.
  29.  * 
  30.  *    Rev 1.11   09 Sep 1992 13:44:30   BCRANE
  31.  * changed MixerRect, RecordRect, and all mixer elements start and end x-coords
  32.  * up 1.
  33.  * 
  34.  *    Rev 1.10   04 Sep 1992 13:24:42   BCRANE
  35.  * changed bottom coordinate of MixerRect
  36.  * 
  37.  *    Rev 1.9   02 Sep 1992 10:03:04   BCRANE
  38.  * added SB volume control
  39.  * 
  40.  *    Rev 1.8   22 Jul 1992 08:21:14   BCRANE
  41.  * added #if USEMIXERGET to use either MixerGetSettings with 
  42.  * callback to "subsavecurrent" or "savecurrent".  Currently set
  43.  * to 1 to use MixerGetSettings.
  44.  * 
  45.  *    Rev 1.7   13 Jul 1992 11:57:02   BCRANE
  46.  * changed F3/SF3 to F5-F8/SF5-SF8
  47.  * now saves setting#.pas where # is 0-3
  48.  * modified F1 help to indicate this new feature 
  49.  * 
  50.  *    Rev 1.6   13 Jul 1992 09:41:56   DCODY
  51.  * GetMixerSettings now reports dead mixer settings
  52.  * 
  53.  *    Rev 1.5   10 Jul 1992 16:57:44   BCRANE
  54.  * changed INPUT to MIXER
  55.  * 
  56.  *    Rev 1.4   10 Jul 1992 16:38:52   BCRANE
  57.  * finalized (!) save and load defaults - handles input/output mixers
  58.  * last-one-active situation, as well as absolute vs. percent values
  59.  * 
  60.  *    Rev 1.3   09 Jul 1992 17:45:16   BCRANE
  61.  * added load and save current state and getdriverpath
  62.  * not fully complete
  63.  * 
  64.  *    Rev 1.2   01 Jul 1992 14:40:58   DCODY
  65.  * added OEM specific wording
  66. *    Rev 1.1   23 Jun 1992 16:44:32   DCODY
  67. * PAS2 update
  68. *    Rev 1.0   15 Jun 1992 09:41:16   BCRANE
  69. * Initial revision.
  70. ;    |*| 
  71. ;    |*| /*$Logfile:   X:/sccs/mixers/dialog.c_v  $
  72. ;    |*| 
  73. ;    |*| /*$Modtimes$
  74. ;    |*| 
  75. ;    \*/
  76.  
  77.     /*\
  78.     |*|---====< DIALOG.C  --  PAS User interface module >====----
  79.     |*|
  80.     |*| Pro Audio Spectrum Mixer User Interface program. This
  81.     |*| program provides mixer control from the command line.
  82.     |*|
  83.     |*| Media Vision, Inc. Copyright (c) 1991, All rights reserved
  84.     |*|
  85.     \*/
  86.  
  87.     /* minor revisions to allow integration with audiolnk (large model) */
  88.  
  89. #include <stdio.h>
  90. #include <stdlib.h>
  91. #include <string.h>
  92. #include <ctype.h>
  93. #include <bios.h>
  94.  
  95. #include <fcntl.h>
  96. #include <sys\types.h>
  97. #include <sys\stat.h>
  98. #include <io.h>
  99.  
  100. #include "dialog.h"
  101. #include <binary.h>
  102.  
  103. #ifndef OEM
  104. #define OEM 0
  105. #endif
  106.  
  107.     /*\
  108.     |*|----====< some prototypes >====----
  109.     \*/
  110.  
  111.         int     EqualizerLevels     ( );
  112.         int     ScrollObjectHandler ( );
  113.         int     SwitchObjectHandler ( );
  114.         int     VolumeLevels        ( );
  115.         int     VolumeButtons        ( );
  116.         int     EffectsButtons        ( );
  117.  
  118.  
  119.     /*\
  120.     |*|----====< global data >====----
  121.     \*/
  122.  
  123. #define TRUE    -1
  124. #define FALSE    0
  125.  
  126.     static char makemenull[]="";
  127.  
  128.     static char *screenlayout[] = {
  129.  
  130.         "┌───────────────────────────────┐",
  131. #if OEM
  132.         "│           Spectrum            │",
  133. #else
  134.         "│Media Vision Pro AudioSpectrum │",
  135. #endif
  136.         "├────────────┬──────────────────┼",
  137.         "│ FM         │││",
  138.         "│ Synthesizer│││",
  139.         "├────────────┼─┤                ├",
  140.         "│ External   │││",
  141.         "│ Jack       │││",
  142.         "├────────────┼─┤                ├",
  143.         "│ Internal   │││",
  144.         "│ Connector  │││",
  145.         "├────────────┼─┤                ├",
  146.         "│ Microphone │││",
  147.         "│ Jack       │││",
  148.         "├────────────┼─┤                ├",
  149.         "│ PC         │││",
  150.         "│ Speaker    │││",
  151.         "├────────────┼─┤                ├",
  152.         "│ SB Digital │││",
  153.         "│ Audio      │││",
  154.         "├────────────┼─┤                ├",
  155.         "│ Digital    │││",
  156.         "│ Audio      │││",
  157.         "└───────────────────────────────┘"
  158.     };
  159.  
  160.     static char *screenlayoutblank[]=
  161.         {
  162.         "├────────────┼─┤                ├",
  163.         "│            ││                │",
  164.         "│            ││                │"
  165.         };
  166.  
  167.     static char *screen2[] = {
  168.  
  169.         "┌────────┬────────────────┬─┐",
  170.         "│Volume  │ Volume Control │ │",
  171.         "├──────┬─┼────────────────┼─┤",
  172.         "│Left  ││││",
  173.         "│Right ││││",
  174.         "├──────┼─┤                ├─┤",
  175.         "│Bass  ││││",
  176.         "├──────┼─┤                ├─┤",
  177.         "│Treble││││",
  178.         "└──────┴─┴────────────────┴─┘",
  179.         "┌───────────┬─┬───────────┬─┐",
  180.         "│ Loudness  ││ Enhanced  ││",
  181.         "└───────────┴─┴───────────┴─┘",
  182.  
  183.     };
  184.  
  185.     static char *screen3[] = {
  186.  
  187.         "─╔══════╗",
  188.         "║Play &║",
  189.         "║Record║",
  190.         "─╠══════╣",
  191.         "║Play &║",
  192.         "║Record║",
  193.         "─╠══════╣",
  194.         "║Play &║",
  195.         "║Record║",
  196.         "─╠══════╣",
  197.         "║Play &║",
  198.         "║Record║",
  199.         "─╠══════╣",
  200.         "║Play &║",
  201.         "║Record║",
  202.         "─╠══════╣",
  203.         "║Play &║",
  204.         "║Record║",
  205.         "─╠╦╦╦╦╦╦╣",
  206.         "╠╬╬╬╬╬╬╣",
  207.         "╠╬╬╬╬╬╬╣",
  208.         "─╚╩╩╩╩╩╩╝",
  209.  
  210.     };
  211.  
  212.     static char *screen3blank[]= {
  213.         "─╠══════╣",
  214.         "║      ║",
  215.         "║      ║"
  216.         };
  217.  
  218.  
  219.     static char *screen4[] = {       /* Help2rect                         */
  220.  
  221.         "┌───────────────────────────┐",
  222.         "│ Type the F1 key for help. │",
  223.         "└───────────────────────────┘"
  224.     };
  225.  
  226.     static char EffectsString[] = "▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒";
  227.  
  228.     static char *effectsbkgn[] = {
  229.         EffectsString,
  230.         EffectsString,
  231.         EffectsString,
  232.         EffectsString,
  233.         EffectsString,
  234.       EffectsString,
  235.         EffectsString,
  236.         EffectsString,
  237.         EffectsString,
  238.         EffectsString,
  239.         EffectsString,
  240.         EffectsString,
  241.         EffectsString,
  242.         EffectsString,
  243.         EffectsString,
  244.         EffectsString,
  245.         EffectsString,
  246.       EffectsString,
  247.       EffectsString,
  248.       EffectsString,
  249.       EffectsString,
  250.         EffectsString
  251.     };
  252.  
  253.     static char *screen5[] = {       /* input mixer helps                 */
  254.  
  255.         "┌───────────────────────────┐",
  256.         "│    Channel Connections    │",
  257.         "├────────┬─────────┬────────┤",
  258.         "│ Left   ││ Left   │",
  259.         "│ Left   ││ Right  │",
  260.         "│ Right  ││ Left   │",
  261.         "│ Right  ││ Right  │",
  262.         "└────────┴─────────┴────────┘"
  263.     };
  264.  
  265.     static char *screen6[] = {       /* input mixer helps                 */
  266.         "┌───────────────────────────┐",
  267.         "│  Recording Monitor Level  │",
  268.         "├──────┬─┬────────────────┬─┤",
  269.         "│Left  ││││",
  270.         "│Right ││││",
  271.         "└──────┴─┴────────────────┴─┘"
  272.     };
  273.  
  274.     static char *screen7[] = {       /* realsound switch                    */
  275.  
  276.         "┌─────────────────────────┬─┐",
  277.         "│   Real Sound Support    ││",
  278.         "└─────────────────────────┴─┘"
  279.     };
  280.  
  281.     static char playmsgi1[] = "Play &";
  282.     static char playmsgi2[] = "Record";
  283.     static char playmsgo1[] = "Play  ";
  284.     static char playmsgo2[] = "Only  ";
  285.  
  286.     static char *helpscreen[] = {
  287.  
  288.         "╔═══════════════════════════════╗",
  289. #if OEM
  290.         "║           Spectrum            ║",
  291.         "║                               ║",
  292. #else
  293.         "║    Pro AudioSpectrum,  V1.21  ║",
  294.         "║      By Media Vision, Inc.    ║",
  295. #endif
  296.         "╟───────────────────────────────╢",
  297.         "║        Keyboard Control       ║",
  298.         "║       ──────────────────      ║",
  299.         "║HOME  to decrease left volume  ║",
  300.         "║     to decrease both volumes ║",
  301.         "║ END  to decrease right volume ║",
  302.         "║PGUP  to increase left volume  ║",
  303.         "║  3   to increase both volumes ║",
  304.         "║PGDN  to increase right volume ║",
  305.         "║ENTER to toggle a button on/off║",
  306.         "║ TAB  to move between fields   ║",
  307.         "║ F4   reset mixer to defaults  ║",
  308.         "║ F2   special effects          ║",
  309.         "║F5-F8 load mixer settings (use ║",
  310.         "║      Shifted-FKEY to save)    ║",
  311.         "║ ESC  will exit all dialogs    ║",
  312.         "║       ──────────────────      ║",
  313.         "║       Copyright (c) 1991      ║",
  314.         "║      All Rights Reserved.     ║",
  315.         "╚═══════════════════════════════╝"
  316.     };
  317.  
  318.  
  319.         static char twobar[]            = "·····∙∙∙∙∙";
  320.         static char channelconnect[]    = "";
  321.         static char channeldisconnect[] = "· · · · ·";
  322.  
  323.         extern char leftswitch;
  324.         extern int    leftvolume;
  325.         extern char ritswitch;
  326.         extern int    ritvolume;
  327.         extern int    VolumeNumber;
  328.         extern char VolumeSwitch;
  329.         extern int    Left2LeftState;
  330.         extern int    Left2RightState;
  331.         extern int    Right2LeftState;
  332.         extern int    Right2RightState;
  333.  
  334.     //    static char NumLockState;
  335.  
  336.         static VideoStruct OurWnd = { 0,0,0x18,0x4f, 0,0, 0x1f,0, 0,0xb800 };
  337.         VideoStruct *CurWnd = &OurWnd;
  338.         unsigned int VideoSegment = 0xb800;
  339.  
  340.         static rect Help1Rect  = { 1,23, 23,57 };
  341.         static rect Help2Rect  = {19,47, 21,77 };
  342.         static rect MixerRect  = { 0, 2, 23,36 };
  343.         static rect RecordRect = { 2,35, 23,45 };
  344.         static rect VolRect    = { 4,47, 16,77 };
  345.         static rect EffectsRect = { 1,20, 22,60 };
  346.         static rect Screen6Rect = { 2,25,  7,55 };
  347.         static rect Screen5Rect = { 9,25, 16,55 };
  348.         static rect Screen7Rect = {18,25, 20,55 };
  349.  
  350.     /* file handle for accessing MVPROAS                                */
  351.  
  352.         static int    mv;             /* mvsound dos driver                */
  353.  
  354.     /* objects                                                            */
  355.  
  356. #define OBJ_SCROLL        1
  357. #define OBJ_VOLUME        2
  358. #define OBJ_BUTTON        3
  359.  
  360.         typedef struct {
  361.             int  type;                // structure type
  362.             void *next;             // next structure pointer
  363.             void *back;             // prior structure pointer
  364.             int (*scr)();            // object processor
  365.             int (*swi)();            // object processor
  366.             rect namr;                // channel name rectangle
  367.             rect scrr;                // scroll bar rectangle
  368.             rect swir;                // record mixer select switch rectangle
  369.             char name[10];            // channel name "mic"/"ext", etc
  370.             int leftchannel;        // current left channel setting
  371.             int ritchannel;         // current right channel setting
  372.             int mixerselect;        // choosen mixer
  373.             int deadlchannel;        // current left channel setting
  374.             int deadrchannel;        // current right channel setting
  375.             int deadmixer;            // choosen mixer
  376.  
  377.         } Scroll, *SPtr;
  378.  
  379.         typedef struct {
  380.             int  type;                // structure type
  381.             void *next;             // next structure pointer
  382.             void *back;             // prior structure pointer
  383.             int (*scr)();            // object processor
  384.             rect namr;                // channel name rectangle
  385.             rect scrr;                // scroll bar rectangle
  386.             char name[20];            // channel name "mic"/"ext", etc
  387.             int channel;            // current channel setting
  388.         } Volume, *VPtr;
  389.  
  390.         typedef struct {
  391.             int  type;                // structure type
  392.             void *next;             // next structure pointer
  393.             void *back;             // prior structure pointer
  394.             int (*scr)();            // object processor
  395.             rect namr;                // channel name rectangle
  396.             rect scrr;                // scroll bar rectangle
  397.             char name[20];            // channel name "mic"/"ext", etc
  398.             int state;                // current button state
  399.         } Button, *BPtr;
  400.  
  401.         typedef struct {
  402.             void *head;
  403.             void *tail;
  404.             void *nextlist;
  405.         } ObjectList, *OLPtr;
  406.  
  407.     // Scroll bar objects
  408.  
  409.         static Scroll SynthScroll;           // structure prototypes
  410.         static Scroll ExtScroll;
  411.         static Scroll IntScroll;
  412.         static Scroll MicScroll;
  413.         static Scroll DigitalScroll;
  414.         static Scroll TBScroll;
  415.         static Scroll SpkrScroll;
  416.         static Scroll OutputMixerScroll;
  417.  
  418.         static Volume LeftVolumeLevel;
  419.         static Volume RitVolumeLevel;
  420.         static Volume BassVolume;
  421.         static Volume TrebVolume;
  422.  
  423.         static Button Loudness;
  424.         static Button Enhanced;
  425.         static Button Left2Left;
  426.         static Button Left2Right;
  427.         static Button Right2Left;
  428.         static Button Right2Right;
  429.         static Button RealSoundButton;
  430.  
  431.         static ObjectList MainList;
  432.         static ObjectList EffectsList;
  433.  
  434.         static ObjectList MainList = {
  435.             &SynthScroll,
  436.             &Enhanced,
  437.             &EffectsList
  438.         };
  439.  
  440.         static ObjectList EffectsList = {
  441.             &OutputMixerScroll,
  442.             &RealSoundButton,
  443.             0
  444.         };
  445.  
  446.         static OLPtr   CurrList = &MainList;
  447.  
  448.         static Scroll *CurrentObject = &SynthScroll;  // current object pointer
  449.  
  450.         static Scroll SynthScroll = {
  451.             OBJ_SCROLL,
  452.             &ExtScroll,
  453.             0,
  454.             &ScrollObjectHandler,
  455.             &SwitchObjectHandler,
  456.              3, 3, 4,14,
  457.              3,18, 4,33,
  458.              3,37, 4,42,
  459.             "FM ",
  460.             0,
  461.             0,
  462.             0,0,0,0
  463.         };
  464.  
  465.         static Scroll ExtScroll = {
  466.             OBJ_SCROLL,
  467.             &IntScroll,
  468.             &SynthScroll,
  469.             &ScrollObjectHandler,
  470.             &SwitchObjectHandler,
  471.              6, 3, 7,14,
  472.              6,18, 7,33,
  473.              6,37, 7,42,
  474.             "EXT ",
  475.             0,
  476.             0,
  477.             0,0,0,0
  478.         };
  479.  
  480.         static Scroll IntScroll = {
  481.             OBJ_SCROLL,
  482.             &MicScroll,
  483.             &ExtScroll,
  484.             &ScrollObjectHandler,
  485.             &SwitchObjectHandler,
  486.              9, 3,10,14,
  487.              9,18,10,33,
  488.              9,37,10,42,
  489.             "INT ",
  490.             0,
  491.             0,
  492.             0,0,0,0
  493.         };
  494.  
  495.         static Scroll MicScroll = {
  496.             OBJ_SCROLL,
  497.             &SpkrScroll,
  498.             &IntScroll,
  499.             &ScrollObjectHandler,
  500.             &SwitchObjectHandler,
  501.             12, 3,13,14,
  502.             12,18,13,33,
  503.             12,37,13,42,
  504.             "MIC ",
  505.             0,
  506.             0,
  507.             0,0,0,0
  508.         };
  509.  
  510.         static Scroll SpkrScroll = {
  511.             OBJ_SCROLL,
  512.             &TBScroll,
  513.             &MicScroll,
  514.             &ScrollObjectHandler,
  515.             &SwitchObjectHandler,
  516.             15, 3,16,14,
  517.             15,18,16,33,
  518.             15,37,16,42,
  519.             "SPEAKER ",
  520.             0,
  521.             0,
  522.             0,0,0,0
  523.         };
  524.  
  525.         static Scroll TBScroll = {
  526.             OBJ_SCROLL,
  527.             &DigitalScroll,
  528.             &SpkrScroll,
  529.             &ScrollObjectHandler,
  530.             &SwitchObjectHandler,
  531.             18, 3,19,14,
  532.             18,18,19,33,
  533.             18,37,19,42,
  534.             "SB      ",
  535.             0,
  536.             0,
  537.             0,0,0,0
  538.         };
  539.  
  540.         static Scroll DigitalScroll = {
  541.             OBJ_SCROLL,
  542.             &LeftVolumeLevel,
  543.             &TBScroll,
  544.             &ScrollObjectHandler,
  545.             0,
  546.             21, 3,22,14,
  547.             21,18,22,33,
  548.             21,37,22,42,
  549.             "PCM ",
  550.             0,
  551.             0,
  552.             0,0,0,0
  553.         };
  554.  
  555.         static Volume LeftVolumeLevel = {
  556.             OBJ_VOLUME,
  557.             &BassVolume,
  558.             &DigitalScroll,
  559.             &VolumeLevels,
  560.              7,48, 7,53,
  561.              7,57, 7,72,
  562.             "LEVEL ",
  563.             0
  564.         };
  565.  
  566.             // this object is owned byte LeftVolumeLevel
  567.  
  568.                 static Volume RitVolumeLevel  = {
  569.                     OBJ_VOLUME,
  570.                     0,
  571.                     0,
  572.                     &VolumeLevels,
  573.                      8,48, 8,53,
  574.                      8,57, 8,72,
  575.                     "LEVEL ",
  576.                     0
  577.                 };
  578.  
  579.         static Volume BassVolume = {
  580.             OBJ_VOLUME,
  581.             &TrebVolume,
  582.             &LeftVolumeLevel,
  583.             &EqualizerLevels,
  584.             10,48,10,53,
  585.             10,57,10,72,
  586.             "BASS ",
  587.             0
  588.         };
  589.  
  590.         static Volume TrebVolume = {
  591.             OBJ_VOLUME,
  592.             &Loudness,
  593.             &BassVolume,
  594.             &EqualizerLevels,
  595.             12,48,12,53,
  596.             12,57,12,72,
  597.             "TREBLE ",
  598.             0
  599.         };
  600.  
  601.         static Button Loudness    = {
  602.             OBJ_BUTTON,
  603.             &Enhanced,
  604.             &TrebVolume,
  605.             &VolumeButtons,
  606.             15,48,15,58,
  607.             15,60,15,60,
  608.             "LOUDNESS ",
  609.             0
  610.         };
  611.  
  612.         static Button Enhanced = {
  613.             OBJ_BUTTON,
  614.             0,
  615.             &Loudness,
  616.             &VolumeButtons,
  617.             15,63,15,72,
  618.             15,74,15,74,
  619.             "ENHANCED ",
  620.             0
  621.         };
  622.  
  623.  
  624.     /*\
  625.     |*| effects dialog box structures
  626.     \*/
  627.  
  628.         static Scroll OutputMixerScroll = {
  629.             OBJ_SCROLL,
  630.             &Left2Left,
  631.             0,
  632.             &ScrollObjectHandler,
  633.             0,
  634.             5,26,6,31,
  635.             5,35,6,50,
  636.              0, 0, 0, 0,
  637.             "MIXER ",
  638.             0,
  639.             0,
  640.             0,0,0,0
  641.         };
  642.  
  643.         static Button Left2Left = {
  644.             OBJ_BUTTON,
  645.             &Left2Right,
  646.             &OutputMixerScroll,
  647.             &EffectsButtons,
  648.             12,26,12,33,
  649.             12,35,12,43,
  650.             "Left to Left ",
  651.             0
  652.         };
  653.  
  654.         static Button Left2Right = {
  655.             OBJ_BUTTON,
  656.             &Right2Left,
  657.             &Left2Left,
  658.             &EffectsButtons,
  659.             13,26,13,33,
  660.             13,35,13,43,
  661.             "Left to Right ",
  662.             0
  663.         };
  664.  
  665.         static Button Right2Left = {
  666.             OBJ_BUTTON,
  667.             &Right2Right,
  668.             &Left2Right,
  669.             &EffectsButtons,
  670.             14,26,14,33,
  671.             14,35,14,43,
  672.             "Right to Left ",
  673.             0
  674.         };
  675.  
  676.         static Button Right2Right = {
  677.             OBJ_BUTTON,
  678.             &RealSoundButton,
  679.             &Right2Left,
  680.             &EffectsButtons,
  681.             15,26,15,33,
  682.             15,35,15,43,
  683.             "Right to Right ",
  684.             0
  685.         };
  686.  
  687.         static Button RealSoundButton = {
  688.             OBJ_BUTTON,
  689.             0,
  690.             &Right2Left,
  691.             &EffectsButtons,
  692.             19,26,19,49,
  693.             19,52,19,52,
  694.             " ",
  695.             0
  696.         };
  697.  
  698.         static int OrigRow;            // original row position
  699.         static int OrigCol;            // original column position
  700.  
  701.         static char CommandString[80]; // text buffer that holds commands to MVPROAS
  702.         static char MVResponse[80];    // text buffer that holds the MVPROAS responses
  703.  
  704.         static int screenbuffer[2048]; // screen backup buffer
  705.  
  706. #define MAIN_DLG        0x0001    // main screen dialog boxes
  707. #define EFFECTS_DLG     0x0002    // recording effects dialog box
  708.  
  709.         static int DialogBox=MAIN_DLG; // bit field indicating witch dialog box is up
  710.  
  711.  
  712.         typedef struct {
  713.  
  714.             int Filler;         // all other screen area
  715.  
  716.             int BkGn_AND;       // background AND mask
  717.             int BkGn_XOR;        // background XOR mask
  718.  
  719.             int Shdw_AND;       // shadow AND mask
  720.             int Shdw_XOR;        // shadow XOR mask
  721.  
  722.             int TmpHi_AND;      // temp High AND mask
  723.             int TmpHi_XOR;        // temp high XOR mask
  724.  
  725.             int TmpLo_AND;      // temp low  AND mask
  726.             int TmpLo_XOR;        // temp low  XOR mask
  727.  
  728.             int ScrTmpHi_AND;    // temp High AND mask
  729.             int ScrTmpHi_XOR;    // temp high XOR mask
  730.  
  731.             int ScrTmpLo_AND;    // temp low  AND mask
  732.             int ScrTmpLo_XOR;    // temp low  XOR mask
  733.  
  734.             int ButLo_AND;      // button low AND mask
  735.             int ButLo_XOR;        // button low XOR mask
  736.  
  737.             int ButHi_AND;      // button high AND mask
  738.             int ButHi_XOR;        // button high XOR mask
  739.  
  740.         } scheme, *SCMPtr;
  741.  
  742.         static scheme MonoScheme = {   // attribute control for MONO screens
  743.  
  744.             0x0e,                // full bright
  745.  
  746.             0x00,                // background AND mask
  747.             0x07,                // background XOR mask
  748.  
  749.             0x77,                // shadow AND mask
  750.             0x00,                // shadow XOR mask
  751.  
  752.             0x77,                // temp High AND mask
  753.             0x08,                // temp high XOR mask
  754.  
  755.             0x77,                // temp low  AND mask
  756.             0x00,                // temp low  XOR mask
  757.  
  758.             0x77,                // scroll temp High AND mask
  759.             0x08,                // scroll temp high XOR mask
  760.  
  761.             0x77,                // scroll temp low    AND mask
  762.             0x00,                // scroll temp low    XOR mask
  763.  
  764.             0x00,                // button low AND mask
  765.             0x1f,                // button low XOR mask
  766.  
  767.             0x08,                // button high AND mask
  768.             0x70,                // button high XOR mask
  769.  
  770.         };
  771.  
  772.         static scheme ColorScheme = {  // attribute control for COLOR screens
  773.  
  774.             0x09,                // bright blue background
  775.  
  776.             0x00,               // background AND mask
  777.             0x30,                // background XOR mask
  778.  
  779.             0x00,                // shadow AND mask
  780.             0x00,                // shadow XOR mask
  781.  
  782.             0x70,                // temp High AND mask
  783.             0x0e,                // temp high XOR mask
  784.  
  785.             0x70,                // temp low  AND mask
  786.             0x00,                // temp low  XOR mask
  787.  
  788.             0x70,                // scroll temp High AND mask
  789.             0x0e,                // scroll temp high XOR mask
  790.  
  791.             0x70,                // scroll temp low    AND mask
  792.             0x0a,                // scroll temp low    XOR mask
  793.  
  794.             0x00,                // button low AND mask
  795.             0x37,                // button low XOR mask
  796.  
  797.             0x00,                // button high AND mask
  798.             0x3f,                // button high XOR mask
  799.  
  800.         };
  801.  
  802.         static scheme HelpsColorScheme = {    // attribute control for COLOR screens
  803.  
  804.             0x09,                // bright blue
  805.  
  806.             0x00,               // background AND mask
  807.             0x20,                // background XOR mask
  808.  
  809.             0x00,                // shadow AND mask
  810.             0x00,                // shadow XOR mask
  811.  
  812.             0x77,                // temp High AND mask
  813.             0x08,                // temp high XOR mask
  814.  
  815.             0x77,                // temp low  AND mask
  816.             0x00,                // temp low  XOR mask
  817.  
  818.             0x77,                // scroll temp High AND mask
  819.             0x08,                // scroll temp high XOR mask
  820.  
  821.             0x77,                // scroll temp low    AND mask
  822.             0x00,                // scroll temp low    XOR mask
  823.  
  824.             0x08,                // button low AND mask
  825.             0x17,                // button low XOR mask
  826.  
  827.             0x08,                // button high AND mask
  828.             0x70,                // button high XOR mask
  829.  
  830.         };
  831.  
  832.         static SCMPtr  Colors = &ColorScheme;  // default to color adapber scheme
  833.  
  834.  
  835.     /*\
  836.     |*|----====< more prototypes >====----
  837.     \*/
  838.  
  839.         int            MixerDialogInit       ( );
  840.         int            MixerDialogHalt       ( );
  841.         static int       BroadcastMsg        ( int );
  842.         static int       BroadcastToLlist    ( int, ObjectList * );
  843.         static void    DrawScreen           ( rect *, char *([]) );
  844.         static int       GetEvent            ( EPtr );
  845.         static void    MatchObj            ( EPtr );
  846.         static void    PaintScreen           ( int, int );
  847.         static int       PtInRect            ( point *,rect * );
  848.         static int       SendMixer           ( char *, int, int, SPtr, int, int );
  849.         static int       SendVolume           ( char *, int, VPtr, int, int );
  850.  
  851.         static int       SystemKey           ( EPtr );
  852.         static int       SystemInit           ( );
  853.         static void    SystemShutDown       ( );
  854.  
  855.         extern void    BackupVideo           ( rect *, char far *, int, int );
  856.         extern void    RestoreVideo        ( rect *, char far *, int, int );
  857.         long extern    _videogetcurs       ( );  /* ***** was near kdn */
  858.  
  859.  
  860.     /*\
  861.     |*|----------------==============================----------------
  862.     |*|----------------====< Start of Execution >====----------------
  863.     |*|----------------==============================----------------
  864.     \*/
  865.  
  866.         static int exitcode = FALSE;    // our exit flag
  867.         static int CallersFillChar;     // Callers screen fill char (0) for none
  868.  
  869. MixerDialogBox(fill)
  870.     int fill;
  871. {
  872. Event ev;
  873. char *s;
  874.  
  875.     /* make the fill character available to the masses                    */
  876.  
  877.         s = EffectsString;
  878.         if ((CallersFillChar = fill) != 0)
  879.             while (*s) *s++ = fill;
  880.  
  881.     /* initialize the hardware.                                         */
  882.  
  883.         SystemInit();
  884.  
  885.     /* go forever                                                        */
  886.  
  887.         while (!exitcode) {
  888.  
  889.             /* if a keyboard/mouse action, the pass to handlers         */
  890.  
  891.                 if (GetEvent (&ev)) {
  892.                     if (!SystemKey(&ev)) {
  893.                         if (CurrentObject)
  894.                             (*CurrentObject->scr)(OPEVENT,CurrentObject,&ev);
  895.                     }
  896.                 }
  897.  
  898.             /* if no action, just move the cross hairs                    */
  899.  
  900.                 else
  901.                     UpdateTotalVolume();        /* changes via keyboard */
  902.                     MatchObj ( &ev );           /* find a new object    */
  903.         }
  904.  
  905.     /* exit back to caller                                                */
  906.  
  907.         SystemShutDown();
  908.  
  909.     /* reset the exit code so we can process again...                    */
  910.  
  911.         exitcode=FALSE;
  912.  
  913. }
  914.  
  915.  
  916.     /*\
  917.     |*|----====< MixerGetSettings() >====----
  918.     |*|
  919.     |*| call the user back with the appropriate data
  920.     |*|
  921.     |*| Entry Conditions:
  922.     |*|     None
  923.     |*|
  924.     |*| Exit Conditions:
  925.     |*|     0 = okay, !0 = failure
  926.     |*|
  927.     \*/
  928.  
  929. MixerGetSettings(c)
  930.     void (*c)();
  931. {
  932. SPtr o;
  933. OLPtr l;
  934.  
  935.     /* start at the top & send to all objects, even the caller            */
  936.  
  937.         l = &MainList;
  938.  
  939.         while (l) {
  940.  
  941.             o = l->head;
  942.  
  943.             while (o) {
  944.  
  945.                 // send the message to the next object
  946.  
  947.                     (*o->scr)(OPENINIT,o);
  948.  
  949.                     // if the dead mixer, then send this string too!
  950.  
  951.                     if (o->type == OBJ_SCROLL) {
  952.                         SendMixer ("SET ",o->deadmixer,1,o,BI_SETTO,o->deadlchannel);
  953.                         (*c)(&CommandString);
  954.                         SendMixer ("SET ",o->deadmixer,2,o,BI_SETTO,o->deadrchannel);
  955.                         (*c)(&CommandString);
  956.                     }
  957.                     (*o->scr)(SENDIT,o,c);
  958.  
  959.                 // go to next object
  960.  
  961.                     o = o->next;
  962.             }
  963.  
  964.             l = l->nextlist;
  965.         }
  966. }
  967.  
  968.  
  969.     /*\
  970.     |*|----====< MixerDialogInit() >====----
  971.     |*|
  972.     |*| Perform any startup needed
  973.     |*|
  974.     |*| Entry Conditions:
  975.     |*|     None
  976.     |*|
  977.     |*| Exit Conditions:
  978.     |*|     0 = okay, !0 = failure
  979.     |*|
  980.     \*/
  981. int MixerDialogInit()
  982. {
  983.  
  984.     // open the device
  985.  
  986.         //if ((mv = open ("MVPROAS",O_RDWR, S_IREAD | S_IWRITE)) == -1) {
  987.  
  988.         if ((mv = open ("MVPROAS",O_RDWR )) == -1) {
  989.           //_ttyout ("\acannot open the MVPROAS device!\n",0);
  990.             return(1);
  991.         }
  992.  
  993.     // make an IBM PC right arrow appear in some text
  994.  
  995.         helpscreen[10][3]= 26;    /* used to be:        hackaline[3] = 26; */
  996.  
  997.     // everything is fine...
  998.  
  999.         return (0);
  1000.  
  1001. }
  1002.  
  1003.  
  1004.     /*\
  1005.     |*|----====< MixerDialogHalt() >====----
  1006.     |*|
  1007.     |*| Perform any other shutdown
  1008.     |*|
  1009.     |*| Entry Conditions:
  1010.     |*|     None
  1011.     |*|
  1012.     |*| Exit Conditions:
  1013.     |*|     0 = okay, !0 = failure
  1014.     |*|
  1015.     \*/
  1016. int  MixerDialogHalt()
  1017. {
  1018.  
  1019.     // close down the file handle
  1020.  
  1021.         close (mv);
  1022.  
  1023.     // everything is fine...
  1024.  
  1025.         return (0);
  1026.  
  1027. }
  1028.  
  1029.  
  1030.     /*\
  1031.     |*|--------------------=======================--------------------
  1032.     |*|--------------------====< Subroutines >====--------------------
  1033.     |*|--------------------=======================--------------------
  1034.     \*/
  1035.  
  1036.  
  1037.     /*\
  1038.     |*|----====< void BroadcastMsg ( int ) >====----
  1039.     |*|
  1040.     |*|    This routine broadcasts a message to all objects.
  1041.     |*|
  1042.     \*/
  1043. static int BroadcastMsg (msg)
  1044.     int msg;
  1045. {
  1046. SPtr o;
  1047.  
  1048.     /* send to all linked lists of objects                                */
  1049.  
  1050.         BroadcastToList (msg,&MainList);
  1051.         BroadcastToList (msg,&EffectsList);
  1052. }
  1053.  
  1054.  
  1055.     /*\
  1056.     |*|----====< void BroadcastToList ( int, ObjectList * ) >====----
  1057.     |*|
  1058.     |*|    This routine broadcasts a message to all objects.
  1059.     |*|
  1060.     \*/
  1061. static int BroadcastToList (msg,l)
  1062.     int msg;
  1063.      ObjectList *l;
  1064. {
  1065. SPtr o;
  1066.  
  1067.     /* start at the top & send to all objects, even the caller            */
  1068.  
  1069.         o = l->head;
  1070.  
  1071.         while (o) {
  1072.  
  1073.             /* send the message to the next object                        */
  1074.  
  1075.                 (*o->scr)(msg,o);
  1076.  
  1077.             /* go to next object                                        */
  1078.  
  1079.                 o = o->next;
  1080.         }
  1081. }
  1082.  
  1083.  
  1084. #if 0
  1085.     /*\
  1086.     |*|----====< void DupTheEvent ( EPtr, EPtr ); >====----
  1087.     |*|
  1088.     |*|    Duplicate our event record.
  1089.     |*|
  1090.     \*/
  1091.         void    DupTheEvent         ( EPtr, EPtr );
  1092. static void DupTheEvent(src,dst)
  1093.     EPtr src,dst;
  1094. {
  1095.  
  1096.     /* duplicate the event using an intrinsic function                    */
  1097.  
  1098.         memcpy
  1099.           (
  1100.             (char *) dst,
  1101.             (char *) src,
  1102.             sizeof (Event)
  1103.           );
  1104. }
  1105. #endif
  1106.  
  1107.  
  1108.     /*\
  1109.     |*|----====< int EffectsButtons() >====----
  1110.     |*|
  1111.     |*| Cross Channel object control
  1112.     |*|
  1113.     |*| Entry Conditions:
  1114.     |*|     None
  1115.     |*|
  1116.     |*| Exit Conditions:
  1117.     |*|     None
  1118.     |*|
  1119.     \*/
  1120. static int EffectsButtons(msg,o,ptr)
  1121.     int msg;
  1122.     BPtr o;
  1123.     void *ptr;
  1124. {
  1125. void **pptr;
  1126. rect r;
  1127. int l,ri,i;
  1128. char c1,c2;
  1129.  
  1130.     // get a pointer to the stack
  1131.  
  1132.         pptr = &ptr;
  1133.  
  1134.     // process the message
  1135.  
  1136.         switch (msg) {
  1137.  
  1138.             case OPEVENT:
  1139.  
  1140.                 switch (((EPtr)pptr[0])->buttons) {
  1141.  
  1142.                     case ENTER:
  1143.  
  1144.                         // ENTER here can toggle the buttons
  1145.  
  1146.                        o->state = ((o->state) ? FALSE : TRUE );
  1147.  
  1148.                         (*o->scr) (DRAWIT,o);
  1149.  
  1150.                         if (o == &RealSoundButton)
  1151.                             SendOnOff ("SET ","REALSOUND ",o);
  1152.                         else
  1153.                             SendOnOff ("SET ","CROSS ",o);
  1154.  
  1155.                         break;
  1156.  
  1157.                     default:
  1158.                         break;
  1159.                 }
  1160.  
  1161.                 break;
  1162.  
  1163.             case SENDIT:
  1164.  
  1165.                 if (o == &RealSoundButton)
  1166.                     SendOnOff ("SET ","REALSOUND ",o);
  1167.                 else
  1168.                     SendOnOff ("SET ","CROSS ",o);
  1169.  
  1170.                 (*(void(*)())ptr)(&CommandString);
  1171.  
  1172.                 break;
  1173.  
  1174.             case FOCUS_GIVEN:
  1175.  
  1176.                 // highlight the entire field
  1177.  
  1178.                     if (o == &RealSoundButton) {
  1179.  
  1180.                       //r.row2 = o->namr.row2;
  1181.                       //r.row1 = o->namr.row1;
  1182.                       //r.col2 = r.col1 = o->namr.col2+2;
  1183.                       //_videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  1184.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1185.                         _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1186.  
  1187.                     }
  1188.                     else {
  1189.  
  1190.                         r.row1 = o->scrr.row1;
  1191.                         r.row2 = o->scrr.row2;
  1192.                         r.col2 = (r.col1 = o->scrr.col2+2) + 7;
  1193.  
  1194.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1195.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r );
  1196.                         _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1197.                     }
  1198.  
  1199.                     break;
  1200.  
  1201.             case FOCUS_TAKEN:
  1202.  
  1203.                 // remove the highlight from the entire field
  1204.  
  1205.                     if (o == &RealSoundButton) {
  1206.  
  1207.                       //r.row1 = o->namr.row1;
  1208.                       //r.row2 = o->namr.row2;
  1209.                       //r.col2 = r.col1 = o->namr.col2+2;
  1210.                       //_videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &r       );
  1211.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  1212.                         _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1213.  
  1214.                     }
  1215.                     else {
  1216.                         r.row1 = o->scrr.row1;
  1217.                         r.row2 = o->scrr.row2;
  1218.                         r.col2 = (r.col1 = o->scrr.col2+2) + 7;
  1219.  
  1220.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  1221.                         _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1222.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &r );
  1223.                     }
  1224.  
  1225.                     break;
  1226.  
  1227.             case DRAWIT:
  1228.  
  1229.                 // move the cursor to the slide bar area
  1230.  
  1231.                     if (o == &RealSoundButton) {
  1232.  
  1233.                         _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1234.  
  1235.                         if (o->state)
  1236.                             _zipout   ( "X" );
  1237.                         else
  1238.                             _zipout   ( "∙" );
  1239.                     }
  1240.  
  1241.                     else {
  1242.  
  1243.                         _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1244.  
  1245.                         if (o->state)
  1246.                             _zipout ( channelconnect, 0);
  1247.                         else
  1248.                             _zipout ( channeldisconnect, 0);
  1249.                     }
  1250.  
  1251.                 break;
  1252.  
  1253.             case OPENINIT:
  1254.  
  1255.                 // get the output mixer current state
  1256.  
  1257.                     if (o == &RealSoundButton) {
  1258.  
  1259.                         SendOnOff ("GET ","REALSOUND ",o);
  1260.  
  1261.                         o->state = (MVResponse[0] == '+') ? TRUE : FALSE;
  1262.  
  1263.                     }
  1264.                     else {
  1265.  
  1266.                         SendOnOff ("GET ","CROSS ",o);
  1267.  
  1268.                         DecodeCrossChannel (MVResponse);
  1269.  
  1270.                         if (o == &Left2Left)
  1271.                             o->state = Left2LeftState;
  1272.  
  1273.                         if (o == &Left2Right)
  1274.                             o->state = Left2RightState;
  1275.  
  1276.                         if (o == &Right2Left)
  1277.                             o->state = Right2LeftState;
  1278.  
  1279.                         if (o == &Right2Right)
  1280.                             o->state = Right2RightState;
  1281.                     }
  1282.  
  1283.                     break;
  1284.  
  1285.             case CLEARIT:
  1286.             default:
  1287.                 break;
  1288.         }
  1289. }
  1290.  
  1291.  
  1292.  
  1293.     /*\
  1294.     |*|----====< int EqualizerLevels() >====----
  1295.     |*|
  1296.     |*| BASS/TREBLE slide bar object control
  1297.     |*|
  1298.     |*| Entry Conditions:
  1299.     |*|     None
  1300.     |*|
  1301.     |*| Exit Conditions:
  1302.     |*|     None
  1303.     |*|
  1304.     \*/
  1305. static int EqualizerLevels(msg,o,ptr)
  1306.     int msg;
  1307.     VPtr o;
  1308.     void *ptr;
  1309. {
  1310. void **pptr;
  1311. rect r;
  1312. int l,ri,i;
  1313. char c1,c2;
  1314.  
  1315.     // get a pointer to the stack
  1316.  
  1317.         pptr = &ptr;
  1318.  
  1319.     // process the message
  1320.  
  1321.         switch (msg) {
  1322.  
  1323.             case OPEVENT:
  1324.  
  1325.                 switch (((EPtr)pptr[0])->buttons) {
  1326.  
  1327.                     case ENDKEY:
  1328.                     case HOMEKEY:
  1329.                     case LFARROW:
  1330.  
  1331.                         if (o->channel > 0)
  1332.                             o->channel -= 4;
  1333.  
  1334.                         SendVolume
  1335.                           (
  1336.                             "SET ",
  1337.                             0,
  1338.                             o,
  1339.                             BI_SETTO,
  1340.                             o->channel
  1341.                           );
  1342.  
  1343.                         (*o->scr) (DRAWIT,o);
  1344.  
  1345.                         break;
  1346.  
  1347.                     case PGDNKEY:
  1348.                     case PGUPKEY:
  1349.                     case RIARROW:
  1350.  
  1351.                         if (o->channel < 100)
  1352.                             o->channel += 4;
  1353.  
  1354.                         SendVolume
  1355.                           (
  1356.                             "SET ",
  1357.                             0,
  1358.                             o,
  1359.                             BI_SETTO,
  1360.                             o->channel
  1361.                           );
  1362.  
  1363.                         (*o->scr) (DRAWIT,o);
  1364.  
  1365.                         break;
  1366.  
  1367.                     case ENTER:
  1368.  
  1369.                         // ENTER here can toggle the buttons
  1370.  
  1371.                         if (o == &BassVolume)
  1372.                             (*Loudness.scr)(msg,&Loudness,ptr);
  1373.  
  1374.                         if (o == &TrebVolume)
  1375.                             (*Enhanced.scr)(msg,&Enhanced,ptr);
  1376.                         break;
  1377.  
  1378.                     default:
  1379.                         break;
  1380.                 }
  1381.  
  1382.                 break;
  1383.  
  1384.             case SENDIT:
  1385.  
  1386.                 SendVolume
  1387.                   (
  1388.                     "SET ",
  1389.                     0,
  1390.                     o,
  1391.                     BI_SETTO,
  1392.                     o->channel
  1393.                   );
  1394.                 (*(void(*)())ptr)(&CommandString);
  1395.  
  1396.                 break;
  1397.  
  1398.             case FOCUS_GIVEN:
  1399.  
  1400.                 // highlight the entire field
  1401.  
  1402.                     r.row1 = o->namr.row1;
  1403.                     r.row2 = o->namr.row2;
  1404.                     r.col2 = r.col1 = o->namr.col2+2;
  1405.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1406.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  1407.  
  1408.                     r.row1 = o->scrr.row1;
  1409.                     r.row2 = o->scrr.row2;
  1410.                     r.col2 = r.col1 = o->scrr.col2+2;
  1411.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1412.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  1413.  
  1414.                     break;
  1415.  
  1416.             case FOCUS_TAKEN:
  1417.  
  1418.                 // highlight the entire field
  1419.  
  1420.                     r.row1 = o->namr.row1;
  1421.                     r.row2 = o->namr.row2;
  1422.                     r.col2 = r.col1 = o->namr.col2+2;
  1423.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,    &o->namr );
  1424.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1425.  
  1426.                     r.row1 = o->scrr.row1;
  1427.                     r.row2 = o->scrr.row2;
  1428.                     r.col2 = r.col1 = o->scrr.col2+2;
  1429.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1430.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1431.  
  1432.                     break;
  1433.  
  1434.             case DRAWIT:
  1435.  
  1436.                 // move the cursor to the slide bar area
  1437.  
  1438.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1439.                     _zipout       ( twobar, 0);
  1440.  
  1441.                     l = (o->channel * 31) / 100;
  1442.                     _videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
  1443.                     _zipout (((l & 1) ? "▐" : "▌"), 0);
  1444.  
  1445.                     break;
  1446.  
  1447.             case OPENINIT:
  1448.  
  1449.                 // get the output mixer current state
  1450.  
  1451.                     SendVolume ("GET ",0,o,0,0);
  1452.                     DecodeVolumeNumber (MVResponse);
  1453.                     o->channel = VolumeNumber;
  1454.  
  1455.                     break;
  1456.  
  1457.             case CLEARIT:
  1458.             default:
  1459.                 break;
  1460.         }
  1461. }
  1462.  
  1463.  
  1464.     /*\
  1465.     |*|----====< int GetEvent ( EPtr ) >====----
  1466.     |*|
  1467.     |*|   This routine fetches the next event from the mouse driver
  1468.     |*|
  1469.     |*| This routine is used by permission from Douglas S. Cody
  1470.     |*| Douglas S. Cody, Copyright 1989,1990 (c), All Rights Reserved.
  1471.     |*|
  1472.     \*/
  1473. static int GetEvent (e)
  1474.     EPtr e;
  1475. {
  1476.  
  1477.     // if there is a key waiting...
  1478.  
  1479.         if (_bios_keybrd( _KEYBRD_READY )) {
  1480.  
  1481.             // ...return it
  1482.  
  1483.             e->type = EV_KEYB;
  1484.             return (e->buttons =  _bios_keybrd ( _KEYBRD_READ ));
  1485.         }
  1486.  
  1487.     // ...else return 0
  1488.  
  1489.         return( 0 );
  1490.  
  1491. }
  1492.  
  1493.  
  1494.     /*\
  1495.     |*|----====< void MatchObj(EPtr) >====----
  1496.     |*|
  1497.     |*|    This routine matches the mouse pointer to a screen object
  1498.     |*|
  1499.     \*/
  1500. static void MatchObj(e)
  1501.     EPtr e;
  1502. {
  1503. SPtr o;
  1504.  
  1505. #if 0
  1506.     // if this is a mouse type, match it to the list
  1507.  
  1508.         if (e->type == EV_MOUS) {
  1509.  
  1510.             // if point is still within the current object, just return
  1511.  
  1512.                 if (PtInRect ((point *)&e->vpos,&CurrentObject->scrr) ||
  1513.                     PtInRect ((point *)&e->vpos,&CurrentObject->scrr))
  1514.                         return;
  1515.  
  1516.             // we must take the focus away so we don't send bogus mouse events
  1517.  
  1518.                 (*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
  1519.  
  1520.             // the mouse is pointing to something else. try to find it
  1521.  
  1522.                 o = CurrList->head;
  1523.                 while (o) {
  1524.  
  1525.                     if (PtInRect ((point *)&e->vpos,&o->scrr) ||
  1526.                         PtInRect ((point *)&e->vpos,&o->swir)) {
  1527.  
  1528.                         // focus given if the object takes mouse events
  1529.  
  1530.                         CurrentObject = o;
  1531.                         (*o->scr) (FOCUS_GIVEN,o);
  1532.                         break;
  1533.  
  1534.                     }
  1535.                     o = o->next;
  1536.                 }
  1537.         }
  1538. #endif
  1539. }
  1540.  
  1541.  
  1542.     /*\
  1543.     |*|----====< void DrawScreen (rect *, char *argv[]) >====----
  1544.     |*|
  1545.     |*| Perform the screen draw for this screen
  1546.     |*|
  1547.     |*| Entry Conditions:
  1548.     |*|     2 parms
  1549.     |*|
  1550.     |*| Exit Conditions:
  1551.     |*|     None
  1552.     |*|
  1553.     \*/
  1554. static void DrawScreen (r,txt)
  1555.     rect *r;
  1556.     char *txt[];
  1557. {
  1558. rect wr;
  1559. int x;
  1560.  
  1561.     // inner box color
  1562.  
  1563.         wr.row1 = r->row1;
  1564.         wr.row2 = r->row2;
  1565.         wr.col1 = r->col1;
  1566.         wr.col2 = r->col2-2;
  1567.         _videoattr (Colors->BkGn_AND,Colors->BkGn_XOR,&wr);
  1568.  
  1569.     // vertical right side shadow
  1570.  
  1571.         wr.row1 = r->row1+1;
  1572.         wr.row2 = r->row2+1;
  1573.         wr.col1 = r->col2-1;
  1574.         wr.col2 = r->col2+0;
  1575.         _videoattr (Colors->Shdw_AND,Colors->Shdw_XOR,&wr);
  1576.  
  1577.     // horizontal bottom shadow
  1578.  
  1579.         wr.row1 = wr.row2;
  1580.         wr.col1 = r->col1+2;
  1581.         _videoattr (Colors->Shdw_AND,Colors->Shdw_XOR,&wr);
  1582.  
  1583.     // actual text
  1584.  
  1585.         if (txt) {
  1586.             for (x=r->row1;x<=r->row2;x++) {
  1587.                 _videosetcurs (x,r->col1);
  1588.                 _zipout (txt[x-r->row1],0);
  1589.             }
  1590.         }
  1591.  
  1592.     // change some attributes on the color screen
  1593.  
  1594.         if (VideoSegment == 0xb800)
  1595.             ChangeAttributes (r->row1, r->col1, r->row2, r->col2-2);
  1596. }
  1597.  
  1598.  
  1599.     /*\
  1600.     |*|----====< PaintScreen (int,int) >====----
  1601.     |*|
  1602.     |*| Draw/Restore the screen
  1603.     |*|
  1604.     |*| Entry Conditions:
  1605.     |*|     INT is a TRUE/FALSE flag
  1606.     |*|     INT is a WIPE or DISSOLVE to original flag
  1607.     |*|
  1608.     |*| Exit Conditions:
  1609.     |*|     None
  1610.     |*|
  1611.     \*/
  1612. static void PaintScreen (tf,fl)
  1613.     int tf;
  1614.     int fl;
  1615. {
  1616. rect r;
  1617.  
  1618. static int backedup = FALSE;
  1619.  
  1620.     if (tf) {            // paint the screen
  1621.  
  1622.         if (!backedup)
  1623.             BackupVideo ( &OurWnd.wndr, (char far *)&screenbuffer[0], 0, 0 );
  1624.  
  1625.         backedup = TRUE;
  1626.  
  1627.         if (CallersFillChar)
  1628.             _videofill ( CallersFillChar, Colors->Filler, &OurWnd.wndr );
  1629.  
  1630.         DrawScreen ( &MixerRect,  &screenlayout[0] );
  1631.         r.row2 = r.row1 = MixerRect.row1+1;
  1632.         r.col1 = MixerRect.col1+1;
  1633.         r.col2 = MixerRect.col2-3;
  1634.         _videoattr ( Colors->ButHi_AND, Colors->ButHi_XOR,&r);
  1635.  
  1636.         DrawScreen ( &RecordRect, &screen3[0] );
  1637.         DrawScreen ( &VolRect,      &screen2[0] );
  1638.         DrawScreen ( &Help2Rect,  &screen4[0] );
  1639.  
  1640.     }
  1641.  
  1642.     else {
  1643.  
  1644.         if (backedup) {
  1645.  
  1646.             if (fl)
  1647.                 dissolve (25,80,(char far *)&screenbuffer[0]);
  1648.             else
  1649.                 RestoreVideo ( &OurWnd.wndr, (char far *) &screenbuffer[0], 0, 0 );
  1650.  
  1651.             backedup = FALSE;
  1652.         }
  1653.     }
  1654. }
  1655.  
  1656.  
  1657.     /*\
  1658.     |*|----====< ProcessRecordEffects (int) >====----
  1659.     |*|
  1660.     |*| Process the Effects dialog box
  1661.     |*|
  1662.     |*| Entry Conditions:
  1663.     |*|     None
  1664.     |*|
  1665.     |*| Exit Conditions:
  1666.     |*|     None
  1667.     |*|
  1668.     \*/
  1669. static void ProcessRecordEffects(msg)
  1670.     int msg;
  1671. {
  1672. rect r;
  1673.  
  1674. static void *ol;
  1675. static void *effectslastobj;
  1676. static void *effectscurrobj;
  1677.  
  1678.         switch (msg) {
  1679.  
  1680.             case DRAWIT:
  1681.                 DrawScreen ( &EffectsRect, &effectsbkgn[0] );
  1682.                 DrawScreen ( &Screen6Rect, &screen6[0]       );
  1683.                 DrawScreen ( &Screen5Rect, &screen5[0]       );
  1684.                 DrawScreen ( &Screen7Rect, &screen7[0]       );
  1685.                 BroadcastToList (DRAWIT,CurrList);    // draw the controls
  1686.                 break;
  1687.  
  1688.             case FOCUS_GIVEN:
  1689.  
  1690.                 // let the current object know its not in foreground
  1691.  
  1692.                     (*CurrentObject->scr)(FOCUS_TAKEN,CurrentObject);
  1693.  
  1694.                 // switch linked lists and current objects
  1695.  
  1696.                     ol = CurrList;                    // switch object lists
  1697.                     CurrList = &EffectsList;
  1698.  
  1699.                     effectslastobj = CurrentObject; // switch objects
  1700.                     if ((CurrentObject = effectscurrobj) == 0)
  1701.                         CurrentObject = CurrList->head;
  1702.  
  1703.                 // paint the screen
  1704.  
  1705.                     ProcessRecordEffects(DRAWIT);
  1706.  
  1707.                     (*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // highlight
  1708.  
  1709.                 // all done till a FOCUS_TAKEN is received
  1710.  
  1711.                     break;
  1712.  
  1713.             case FOCUS_TAKEN:
  1714.  
  1715.                 // let the current object know its not in foreground
  1716.  
  1717.                     (*CurrentObject->scr)(FOCUS_TAKEN,CurrentObject);
  1718.  
  1719.                 // switch linked lists and current objects
  1720.  
  1721.                     CurrList = ol;                    // restore the old list
  1722.  
  1723.                     effectscurrobj = CurrentObject; // switch objects
  1724.                     if (effectslastobj)
  1725.                         CurrentObject  = effectslastobj;
  1726.  
  1727.                 // restore the screen
  1728.  
  1729.                     PaintScreen     (FALSE,FALSE);        // restore the screen
  1730.                     PaintScreen     (TRUE,FALSE);        // put up the screen
  1731.                     BroadcastToList (DRAWIT,CurrList);    // draw the controls
  1732.  
  1733.                     (*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // highlight
  1734.  
  1735.                     break;
  1736.  
  1737.                 default:
  1738.                     break;
  1739.  
  1740.             }
  1741. }
  1742.  
  1743.  
  1744.  
  1745.     /*\
  1746.     |*|----====< PtInRect (point *, rect *) >====----
  1747.     |*|
  1748.     |*| return TRUE if point is within the rectangle
  1749.     |*|
  1750.     |*| Entry Conditions:
  1751.     |*|     None
  1752.     |*|
  1753.     |*| Exit Conditions:
  1754.     |*|     None
  1755.     |*|
  1756.     \*/
  1757. static int PtInRect (p,r)
  1758.     point *p;
  1759.     rect  *r;
  1760. {
  1761.  
  1762.     if ((p->row < r->row1) && (p->row >= r->row2))
  1763.         return(FALSE);
  1764.     if ((p->col < r->col1) && (p->col >= r->col2))
  1765.         return(FALSE);
  1766.  
  1767.     return (TRUE);
  1768. }
  1769.  
  1770.  
  1771.     /*\
  1772.     |*|----====< int ScrollObjectHandler() >====----
  1773.     |*|
  1774.     |*| Scroll bar object control
  1775.     |*|
  1776.     |*| Entry Conditions:
  1777.     |*|     None
  1778.     |*|
  1779.     |*| Exit Conditions:
  1780.     |*|     None
  1781.     |*|
  1782.     \*/
  1783. static int ScrollObjectHandler (msg,o,ptr)
  1784.     int msg;
  1785.     SPtr o;
  1786.     void *ptr;
  1787. {
  1788. void **pptr;
  1789. rect r;
  1790. int l,ri,i,key;
  1791. char c1,c2;
  1792.  
  1793.     // get a pointer to the stack
  1794.  
  1795.         pptr = &ptr;
  1796.  
  1797.     // process the message
  1798.  
  1799.         switch (msg) {
  1800.  
  1801.             case OPEVENT:
  1802.  
  1803.                 key = 0;
  1804.  
  1805.                 switch (((EPtr)pptr[0])->buttons) {
  1806.  
  1807.                     case ENDKEY:                // right = 2;
  1808.                         key++;
  1809.                     case HOMEKEY:                // left  = 1;
  1810.                         key++;
  1811.                     case LFARROW:                // both  = 0;
  1812.  
  1813.                         if (key != 2) {         // do LEFT on left/both cases
  1814.  
  1815.                             if (o->leftchannel > 0)
  1816.                                 o->leftchannel -= 3;
  1817.  
  1818.                             SendMixer
  1819.                               (
  1820.                                 "SET ",
  1821.                                 o->mixerselect,
  1822.                                 1,
  1823.                                 o,
  1824.                                 BI_SETTO,
  1825.                                 o->leftchannel
  1826.                               );
  1827.  
  1828.                         }
  1829.  
  1830.                         if (key != 1) {         // do RIGHT on right/both cases
  1831.  
  1832.                             if (o->ritchannel > 0)
  1833.                                 o->ritchannel -= 3;
  1834.  
  1835.                             SendMixer
  1836.                               (
  1837.                                 "SET ",
  1838.                                 o->mixerselect,
  1839.                                 2,
  1840.                                 o,
  1841.                                 BI_SETTO,
  1842.                                 o->ritchannel
  1843.                               );
  1844.  
  1845.                         }
  1846.  
  1847.                         (*o->scr) (DRAWIT,o);
  1848.  
  1849.                         break;
  1850.  
  1851.                     case PGDNKEY:                // right = 2;
  1852.                         key++;
  1853.                     case PGUPKEY:               // left  = 1;
  1854.                         key++;
  1855.                     case RIARROW:                // both  = 0;
  1856.  
  1857.                         if (key != 2) {         // do LEFT on left/both cases
  1858.  
  1859.                             if (o->leftchannel < 100)
  1860.                                 o->leftchannel += 3;
  1861.  
  1862.                             SendMixer
  1863.                               (
  1864.                                 "SET ",
  1865.                                 o->mixerselect,
  1866.                                 1,
  1867.                                 o,
  1868.                                 BI_SETTO,
  1869.                                 o->leftchannel
  1870.                               );
  1871.                         }
  1872.  
  1873.                         if (key != 1) {         // do RIGHT on right/both cases
  1874.  
  1875.                             if (o->ritchannel < 100)
  1876.                                 o->ritchannel += 3;
  1877.  
  1878.                             SendMixer
  1879.                               (
  1880.                                 "SET ",
  1881.                                 o->mixerselect,
  1882.                                 2,
  1883.                                 o,
  1884.                                 BI_SETTO,
  1885.                                 o->ritchannel
  1886.                               );
  1887.                         }
  1888.  
  1889.                         (*o->scr) (DRAWIT,o);
  1890.  
  1891.                         break;
  1892.  
  1893.                     default:
  1894.                         break;
  1895.                 }
  1896.  
  1897.                 break;
  1898.  
  1899.             case SENDIT:
  1900.  
  1901.                 SendMixer ("SET ",o->mixerselect,1,o,BI_SETTO,o->leftchannel);
  1902.                 (*(void(*)())ptr)(&CommandString);
  1903.                 SendMixer ("SET ",o->mixerselect,2,o,BI_SETTO,o->ritchannel);
  1904.                 (*(void(*)())ptr)(&CommandString);
  1905.                 break;
  1906.  
  1907.             case FOCUS_GIVEN:
  1908.  
  1909.                 // highlight the entire field
  1910.  
  1911.                     r.row1 = o->namr.row1;
  1912.                     r.row2 = o->namr.row2;
  1913.                     r.col2 = r.col1 = o->namr.col2+2;
  1914.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1915.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  1916.  
  1917.                     r.row1 = o->scrr.row1;
  1918.                     r.row2 = o->scrr.row2;
  1919.                     r.col2 = r.col1 = o->scrr.col2+2;
  1920.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1921.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  1922.  
  1923.                     if (o->swi)
  1924.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->swir );
  1925.  
  1926.                     break;
  1927.  
  1928.             case FOCUS_TAKEN:
  1929.  
  1930.                 // highlight the entire field
  1931.  
  1932.                     r.row1 = o->namr.row1;
  1933.                     r.row2 = o->namr.row2;
  1934.                     r.col2 = r.col1 = o->namr.col2+2;
  1935.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  1936.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1937.  
  1938.                     r.row1 = o->scrr.row1;
  1939.                     r.row2 = o->scrr.row2;
  1940.                     r.col2 = r.col1 = o->scrr.col2+2;
  1941.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1942.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1943.  
  1944.                     if (o->swi)
  1945.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->swir );
  1946.  
  1947.                     break;
  1948.  
  1949.             case DRAWIT:
  1950.  
  1951.                 // move the cursor to the slide bar area
  1952.  
  1953.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1954.                     _zipout       ( twobar, 0);
  1955.                     _videosetcurs ( o->scrr.row1+1, o->scrr.col1 );
  1956.                     _zipout       ( twobar, 0);
  1957.  
  1958.                     l = (o->leftchannel * 31) / 100;
  1959.                     _videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
  1960.                     _zipout (((l & 1) ? "▐" : "▌"), 0);
  1961.                     l = (o->ritchannel * 31) / 100;
  1962.                     _videosetcurs ( o->scrr.row1+1, o->scrr.col1+(l>>1) );
  1963.                     _zipout (((l & 1) ? "▐" : "▌"), 0);
  1964.  
  1965.                 // display a mixer bar
  1966.  
  1967.                     if (o->swi) {
  1968.  
  1969.                       //if (o->mixerselect == BI_INPUTMIXER)
  1970.                       //    _videoattr (Colors->ButHi_AND,Colors->ButHi_XOR,&o->swir);
  1971.                       //else
  1972.                       //    _videoattr (Colors->ButLo_AND,Colors->ButLo_XOR,&o->swir);
  1973.  
  1974.                         if (o->mixerselect == BI_INPUTMIXER) {
  1975.                             _videosetcurs (o->swir.row1,o->swir.col1);
  1976.                             _zipout (playmsgi1);
  1977.                             _videosetcurs (o->swir.row1+1,o->swir.col1);
  1978.                             _zipout (playmsgi2);
  1979.                         }
  1980.                         else {
  1981.                             _videosetcurs (o->swir.row1,o->swir.col1);
  1982.                             _zipout (playmsgo1);
  1983.                             _videosetcurs (o->swir.row1+1,o->swir.col1);
  1984.                             _zipout (playmsgo2);
  1985.                         }
  1986.                     }
  1987.  
  1988.                 break;
  1989.  
  1990.             case OPENINIT:
  1991.  
  1992.                 // get the output mixer current state
  1993.  
  1994.                 SendMixer ("GET ",BI_OUTPUTMIXER,0,o,0,0);
  1995.                 DecodeMixer (MVResponse);
  1996.  
  1997.                 if (leftswitch == '+') {
  1998.                     o->mixerselect    = BI_OUTPUTMIXER;
  1999.                     o->leftchannel    = leftvolume;
  2000.                 }
  2001.                 else {
  2002.                     o->deadmixer    = BI_OUTPUTMIXER;
  2003.                     o->deadlchannel = leftvolume;
  2004.                 }
  2005.  
  2006.                 if (ritswitch == '+') {
  2007.                     o->mixerselect    = BI_OUTPUTMIXER;
  2008.                     o->ritchannel    = ritvolume;
  2009.                 }
  2010.                 else {
  2011.                     o->deadmixer    = BI_OUTPUTMIXER;
  2012.                     o->deadrchannel = ritvolume;
  2013.                 }
  2014.  
  2015.                 // get the input mixer current state
  2016.  
  2017.                 SendMixer ("GET ",BI_INPUTMIXER,0,o,0,0);
  2018.                 DecodeMixer (MVResponse);
  2019.  
  2020.                 if (leftswitch == '+') {
  2021.                     o->mixerselect    = BI_INPUTMIXER;
  2022.                     o->leftchannel    = leftvolume;
  2023.                 }
  2024.                 else {
  2025.                     o->deadmixer    = BI_INPUTMIXER;
  2026.                     o->deadlchannel = leftvolume;
  2027.                 }
  2028.  
  2029.                 if (ritswitch == '+') {
  2030.                     o->mixerselect    = BI_INPUTMIXER;
  2031.                     o->ritchannel    = ritvolume;
  2032.                 }
  2033.                 else {
  2034.                     o->deadmixer    = BI_INPUTMIXER;
  2035.                     o->deadrchannel = ritvolume;
  2036.                 }
  2037.  
  2038.                 // make sure both inputs are on the same mixer
  2039.  
  2040.                 SendMixer ("SET ",o->mixerselect,1,o,BI_SETTO,o->leftchannel);
  2041.                 SendMixer ("SET ",o->mixerselect,2,o,BI_SETTO,o->ritchannel);
  2042.                 break;
  2043.  
  2044.             case CLEARIT:
  2045.                 break;
  2046.  
  2047.             default:
  2048.                 break;
  2049.         }
  2050. }
  2051.  
  2052.  
  2053.     /*\
  2054.     |*|----====< int SendOnOff( char *, char *, int, VPtr, int, int ) >====----
  2055.     |*|
  2056.     |*| Send a mixer selection
  2057.     |*|
  2058.     |*| Entry Conditions:
  2059.     |*|     char *cmd = "SET", "GET"
  2060.     |*|     VPtr o      = Volume device name
  2061.     |*|     int  v      = new volume setting
  2062.     |*|
  2063.     |*| Exit Conditions:
  2064.     |*|     MVResponse string holds the result
  2065.     |*|
  2066.     \*/
  2067. static int SendOnOff(cmd,dev,o)
  2068.     char *cmd;    // command
  2069.     char *dev;    // device
  2070.     BPtr o;     // channel name & state
  2071.  
  2072. {
  2073.  
  2074.     // build the string
  2075.  
  2076.         strcpy (CommandString,cmd);        // command
  2077.         strcat (CommandString,dev);        // device name
  2078.         strcat (CommandString,o->name);    // input channel
  2079.         strcat (CommandString,((o->state) ? "ON" : "OFF"));
  2080.  
  2081.         SendTextOut (CommandString);
  2082. }
  2083.  
  2084.  
  2085.     /*\
  2086.     |*|----====< int SendMixer( char *, int, int, SPtr, int, int ) >====----
  2087.     |*|
  2088.     |*| Send a mixer selection
  2089.     |*|
  2090.     |*|     char *cmd = "SET", "GET"
  2091.     |*|     int  dev  = INPUTMIXER or OUTPUTMIXER
  2092.     |*|     int  lr   = both(0),left(1),right(2)
  2093.     |*|     VPtr o      = Volume device name
  2094.     |*|     int  f      = function (UP/DOWN/TO)
  2095.     |*|     int  v      = new volume setting
  2096.     |*|
  2097.     |*| Exit Conditions:
  2098.     |*|     MVResponse string holds the result
  2099.     |*|
  2100.     \*/
  2101. static int SendMixer (cmd,dev,lr,o,f,v)
  2102.     char *cmd;    // command
  2103.     int dev;    // device name
  2104.     int lr;     // left/right/both
  2105.     SPtr o;     // input channel name
  2106.     int f;        // movement function
  2107.     int v;        // new mixer value
  2108.  
  2109. {
  2110. char *fs,*ms,*lrs;
  2111. char val[7];
  2112.  
  2113.     // get the text string equvalent for the function
  2114.  
  2115.         switch (lr) {
  2116.  
  2117.             case 1:
  2118.                 lrs = "LEFT ";  // LEFT side only
  2119.                 break;
  2120.  
  2121.             case 2:
  2122.                 lrs = "RIGHT "; // RIGHT side only
  2123.                 break;
  2124.  
  2125.             case 0:             // BOTH
  2126.             default:
  2127.                 lrs = makemenull;
  2128.                 break;
  2129.         }
  2130.  
  2131.     // get the text string equvalent for the function
  2132.  
  2133.         switch (f) {
  2134.             case BI_SETTO:
  2135.                 fs = "TO ";
  2136.                 break;
  2137.  
  2138.             case BI_UPTO:
  2139.                 fs = "UP ";
  2140.                 break;
  2141.  
  2142.             case BI_DOWNTO:
  2143.                 fs = "DOWN ";
  2144.                 break;
  2145.  
  2146.             default:
  2147.                 fs = makemenull;
  2148.                 break;
  2149.         }
  2150.  
  2151.     // correct the value
  2152.  
  2153.         if (v < 0)     v = 0;
  2154.         if (v > 100) v = 100;
  2155.  
  2156.     // build the string
  2157.  
  2158.         ms = (dev == BI_OUTPUTMIXER) ? "OUTPUT MIXER " : "INPUT MIXER ";
  2159.         itoa   (v,val,10);
  2160.  
  2161.         strcpy (CommandString,cmd);          // command
  2162.         strcat (CommandString,ms);             // device name
  2163.         strcat (CommandString,lrs);          // left/right
  2164.         strcat (CommandString,o->name);      // input channel
  2165.         strcat (CommandString,fs);             // function (up/down/to)
  2166.         strcat (CommandString,val);          // new #
  2167.         strcat (CommandString," PERCENT");
  2168.  
  2169.         SendTextOut (CommandString);
  2170. }
  2171.  
  2172.  
  2173.     /*\
  2174.     |*|----====< int SendVolume( char *, int, VPtr, int, int ) >====----
  2175.     |*|
  2176.     |*| Send a mixer selection
  2177.     |*|
  2178.     |*| Entry Conditions:
  2179.     |*|     char *cmd = "SET", "GET"
  2180.     |*|     int  lr   = both(0),left(1),right(2)
  2181.     |*|     VPtr o      = Volume device name
  2182.     |*|     int  f      = function (UP/DOWN/TO)
  2183.     |*|     int  v      = new volume setting
  2184.     |*|
  2185.     |*| Exit Conditions:
  2186.     |*|     MVResponse string holds the result
  2187.     |*|
  2188.     \*/
  2189. static int SendVolume (cmd,lr,o,f,v)
  2190.     char *cmd;    // command
  2191.     int lr;     // left/right/both
  2192.     VPtr o;     // channel name
  2193.     int f;        // movement function
  2194.     int v;        // new mixer value
  2195.  
  2196. {
  2197. char *fs,*ms,*lrs;
  2198. char val[7];
  2199.  
  2200.     // get the text string equvalent for the function
  2201.  
  2202.         switch (lr) {
  2203.  
  2204.             case 1:
  2205.                 lrs = "LEFT ";  // LEFT side only
  2206.                 break;
  2207.  
  2208.             case 2:
  2209.                 lrs = "RIGHT "; // RIGHT side only
  2210.                 break;
  2211.  
  2212.             case 0:             // BOTH
  2213.             default:
  2214.                 lrs = makemenull;
  2215.                 break;
  2216.         }
  2217.  
  2218.     // get the text string equvalent for the function
  2219.  
  2220.         switch (f) {
  2221.             case BI_SETTO:
  2222.                 fs = "TO ";
  2223.                 break;
  2224.  
  2225.             case BI_UPTO:
  2226.                 fs = "UP ";
  2227.                 break;
  2228.  
  2229.             case BI_DOWNTO:
  2230.                 fs = "DOWN ";
  2231.                 break;
  2232.  
  2233.             default:
  2234.                 fs = makemenull;
  2235.                 break;
  2236.         }
  2237.  
  2238.     // correct the value on slide bars
  2239.  
  2240.         if (o->type == OBJ_VOLUME) {
  2241.  
  2242.             // fudge the volume to correct the rounding errors
  2243.  
  2244.             if (++v < 0)   v = 0;
  2245.             if (v > 100) v = 100;
  2246.         }
  2247.  
  2248.     // build the string
  2249.  
  2250.         itoa   (v,val,10);
  2251.  
  2252.         strcpy (CommandString,cmd);          // command
  2253.         strcat (CommandString,"VOLUME ");    // device name
  2254.         strcat (CommandString,lrs);          // left/right
  2255.         strcat (CommandString,o->name);      // input channel
  2256.         strcat (CommandString,fs);             // function (up/down/to)
  2257.  
  2258.         if (o->type == OBJ_VOLUME) {
  2259.             strcat (CommandString,val);      // new #
  2260.             strcat (CommandString," PERCENT");
  2261.         }
  2262.         else
  2263.             strcat (CommandString,((v) ? "ON" : "OFF"));
  2264.  
  2265.         SendTextOut (CommandString);
  2266. }
  2267.  
  2268.  
  2269.     /*\
  2270.     |*|----====< int SendTextOut( char * ) >====----
  2271.     |*|
  2272.     |*| Send a text string to MVPROAS
  2273.     |*|
  2274.     |*| Entry Conditions:
  2275.     |*|     None
  2276.     |*|
  2277.     |*| Exit Conditions:
  2278.     |*|     None
  2279.     |*|
  2280.     \*/
  2281. static int SendTextOut(s)
  2282.     char *s;
  2283. {
  2284. char *b;
  2285.  
  2286.         b = s;
  2287.         while (*b++) ;
  2288.         write (mv,s,b-s);
  2289.  
  2290.         _dlgflushfile(mv);    // the below code is now in dialoga.asm
  2291.         //    _asm {
  2292.         //        mov     bx,mv
  2293.         //        mov     ah,45h
  2294.         //        int     21h
  2295.         //        jnc     thisisbad
  2296.         //        mov     bx,ax
  2297.         //        mov     ah,3eh
  2298.         //        int     21h
  2299.         //    thisisbad:
  2300.         //    }
  2301.  
  2302.        read (mv,MVResponse,80);
  2303.  
  2304.             {
  2305.             char *m= MVResponse;
  2306.  
  2307.             do
  2308.                 if (*m == '\n')
  2309.                     *m= ' ';
  2310.             while (*++m);
  2311.             do
  2312.                 if (*m == ' ')
  2313.                     *m--= '\0';
  2314.                 else
  2315.                     m--;
  2316.             while (isspace(*m));
  2317.             }
  2318.  
  2319. }
  2320.  
  2321.  
  2322.     /*\
  2323.     |*|----====< int SwitchObjectHandler() >====----
  2324.     |*|
  2325.     |*| mixer selection switch object control
  2326.     |*|
  2327.     |*| Entry Conditions:
  2328.     |*|     None
  2329.     |*|
  2330.     |*| Exit Conditions:
  2331.     |*|     None
  2332.     |*|
  2333.     \*/
  2334.  
  2335. static int SwitchObjectHandler(msg,o,ptr)
  2336.     int msg;
  2337.     SPtr o;
  2338.     void *ptr;
  2339. {
  2340. void **pptr;
  2341.  
  2342.     // get a pointer to the stack
  2343.  
  2344.         pptr = &ptr;
  2345.  
  2346.     // process the message
  2347.  
  2348.         switch (msg) {
  2349.  
  2350.             case OPEVENT:
  2351.  
  2352.                 switch (((EPtr)pptr[0])->buttons) {
  2353.  
  2354.                     case ENTER:
  2355.  
  2356.                         // toggle the input/output mixer selection
  2357.  
  2358.                         if (o == &DigitalScroll)
  2359.                             break;
  2360.  
  2361.                         if (o->mixerselect == BI_OUTPUTMIXER)
  2362.                             o->mixerselect = BI_INPUTMIXER;
  2363.                         else
  2364.                             o->mixerselect = BI_OUTPUTMIXER;
  2365.  
  2366.                         SendMixer
  2367.                           (
  2368.                             "SET ",
  2369.                             o->mixerselect,
  2370.                             1,
  2371.                             o,
  2372.                             BI_SETTO,
  2373.                             o->leftchannel
  2374.                           );
  2375.  
  2376.                         SendMixer
  2377.                           (
  2378.                             "SET ",
  2379.                             o->mixerselect,
  2380.                             2,
  2381.                             o,
  2382.                             BI_SETTO,
  2383.                             o->ritchannel
  2384.                           );
  2385.  
  2386.                         (*o->scr) (DRAWIT,o);
  2387.  
  2388.                     default:
  2389.                         break;
  2390.                 }
  2391.                 break;
  2392.  
  2393.             case SENDIT:
  2394.             case FOCUS_GIVEN:
  2395.             case FOCUS_TAKEN:
  2396.             case DRAWIT:
  2397.             case CLEARIT:
  2398.             case OPENINIT:
  2399.             default:
  2400.                 break;
  2401.         }
  2402. }
  2403.  
  2404.  
  2405.  
  2406.     /*\
  2407.     |*|----====< int  SystemKey(EPtr); >====----
  2408.     |*|
  2409.     |*|    Check the event for a system keystroke.
  2410.     |*|
  2411.     \*/
  2412. static int    SystemKey(e)
  2413.     EPtr e;
  2414. {
  2415. Event ev;
  2416. rect r;
  2417. OLPtr ol;
  2418.  
  2419.     // exit if not a keyboard event
  2420.  
  2421.         if (e->type != EV_KEYB)
  2422.             return(0);
  2423.  
  2424.     // process it...
  2425.  
  2426.         switch (e->buttons) {
  2427.  
  2428.             case ESCAPE:
  2429.  
  2430.                 if (DialogBox & EFFECTS_DLG) {
  2431.                     ProcessRecordEffects(FOCUS_TAKEN);
  2432.                     DialogBox &= ~EFFECTS_DLG;
  2433.                 }
  2434.                 else
  2435.                     exitcode = TRUE;
  2436.  
  2437.                 return(1);
  2438.  
  2439.             case ENTER:
  2440.                 if (CurrentObject->type == OBJ_SCROLL) {
  2441.                     if (CurrentObject->swi)
  2442.                         (*CurrentObject->swi) (OPEVENT,CurrentObject,e);
  2443.                 }
  2444.                 else
  2445.                     (*CurrentObject->scr) (OPEVENT,CurrentObject,e);
  2446.                 return(1);
  2447.  
  2448.             case HOMEKEY:
  2449.             case PGDNKEY:
  2450.             case ENDKEY:
  2451.             case PGUPKEY:
  2452.             case PLUSKEY1:
  2453.             case PLUSKEY2:
  2454.             case MINUSKEY1:
  2455.             case MINUSKEY2:
  2456.             case RIARROW:
  2457.             case LFARROW:
  2458.                 (*CurrentObject->scr) (OPEVENT,CurrentObject,e);
  2459.                 return(1);
  2460.  
  2461.             case SH_TABKEY:
  2462.             case UPARROW:
  2463.  
  2464.                 (*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
  2465.  
  2466.                 if (CurrentObject->back)
  2467.                     CurrentObject = CurrentObject->back;
  2468.                 else
  2469.                     CurrentObject = CurrList->tail;
  2470.  
  2471.                 (*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
  2472.                 return(TRUE);
  2473.  
  2474.             case TABKEY:
  2475.             case DNARROW:
  2476.  
  2477.                 (*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
  2478.  
  2479.                 if (CurrentObject->next)
  2480.                     CurrentObject = CurrentObject->next;
  2481.                 else
  2482.                     CurrentObject = CurrList->head;
  2483.  
  2484.                 (*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
  2485.                 return(TRUE);
  2486.  
  2487.             case F1KEY:
  2488.  
  2489.                 // draw the help screen
  2490.  
  2491.                     if (VideoSegment == 0xb800)
  2492.                         Colors = &HelpsColorScheme;
  2493.  
  2494.                     DrawScreen    ( &Help1Rect, &helpscreen[0] );
  2495.  
  2496.                 // do some special highlighting for enhanced looks
  2497.  
  2498.                     if (VideoSegment == 0xb800) {
  2499.  
  2500.                         r.row2 = ( r.row1 = Help1Rect.row1 + 1) + 1;
  2501.                         r.col1 = Help1Rect.col1 + 1;
  2502.                         r.col2 = Help1Rect.col2 - 3;
  2503.  
  2504.                         _videoattr
  2505.                           (
  2506.                             0x00,
  2507.                             0x3f,
  2508.                             &r
  2509.                           );
  2510.                     }
  2511.  
  2512.                 // wait for a keystroke
  2513.  
  2514.                     while (!GetEvent (&ev))  ;
  2515.  
  2516.                     if (VideoSegment == 0xb800)
  2517.                         Colors = &ColorScheme;
  2518.  
  2519.                 // restore the screen
  2520.  
  2521.                     PaintScreen  (FALSE,FALSE);     // restore the screen
  2522.                     PaintScreen  (TRUE,FALSE);        // put up the screen
  2523.                     BroadcastToList (DRAWIT,&MainList); // draw the controls
  2524.  
  2525.                     if (DialogBox & EFFECTS_DLG) {
  2526.                         ProcessRecordEffects(DRAWIT);
  2527.                         BroadcastToList (DRAWIT,&EffectsList);
  2528.                     }
  2529.  
  2530.                     (*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // re-highlight
  2531.                     return(TRUE);
  2532.  
  2533.             case F2KEY:
  2534.  
  2535.                 // try to open and process the effects windows
  2536.  
  2537.                     if (!(DialogBox & EFFECTS_DLG)) {
  2538.  
  2539.                         // do not re-enter
  2540.  
  2541.                             DialogBox |= EFFECTS_DLG;
  2542.  
  2543.                             ProcessRecordEffects(FOCUS_GIVEN);
  2544.                     }
  2545.                     return(TRUE);
  2546.  
  2547.             case F5KEY:    /* F5-F8 load mixer settings from DOS file */
  2548.             case F6KEY: /* subtract F5 scancode from key pressed */
  2549.             case F7KEY: /* move high byte to low and use as index (0-3) */
  2550.             case F8KEY:
  2551.                 loadcurrent((e->buttons- F5KEY)>> 8);    /* open, read setting[0-3].pas and SendTextOut */
  2552.                 BroadcastMsg (OPENINIT); // tell everyone we are starting
  2553.                 BroadcastToList (DRAWIT,CurrList);     // draw the controls
  2554.                 return(TRUE);
  2555.  
  2556.             case SF5KEY: /* Shift F5-F8 save mixer settings into DOS file */
  2557.             case SF6KEY: /* subtract SF5 scancode from key pressed */
  2558.             case SF7KEY: /* move high byte to load and use as index (0-3) */
  2559.             case SF8KEY:
  2560.                 savecurrent((e->buttons- SF5KEY)>> 8); /* save setting[0-3].pas */
  2561.                 return(TRUE);
  2562.  
  2563.             case F4KEY:
  2564.  
  2565.                 // have all objects re-init themselves, then redraw
  2566.  
  2567.                     SendTextOut  ("RESET");  // reset the mixers
  2568.                     BroadcastMsg (OPENINIT); // tell everyone we are starting
  2569.                     BroadcastToList (DRAWIT,CurrList);     // draw the controls
  2570.                     return(TRUE);
  2571.  
  2572.             default:
  2573.                 return(FALSE);
  2574.         }
  2575.  
  2576. }
  2577.  
  2578.  
  2579.     /*\
  2580.     |*|----====< void SystemShutDown(); >====----
  2581.     |*|
  2582.     |*|    Exits to the swapper to exit for good, or loads a program.
  2583.     |*|
  2584.     \*/
  2585. static void SystemShutDown()
  2586. {
  2587.    //    MouseInit        ( OFF,OFF );            // kill the mouse
  2588.  
  2589.    // restore the video
  2590.  
  2591.         PaintScreen   ( FALSE,TRUE );        // take down the screen
  2592.         _videosetcurs ( OrigRow, OrigCol ); // restore the cursor position
  2593.         _videocshape  ( -1, -1);            // now, restore the original shape
  2594.  
  2595.     // restore numlock
  2596.  
  2597.         _dlgrestorenumlock();    // the below code is now in dialoga.asm
  2598.         //    _asm {
  2599.         //        push    es                        ; save the numlock state
  2600.         //        sub     ax,ax
  2601.         //        mov     es,ax
  2602.         //        mov     al,NumLockState
  2603.         //        or        es:[0x417],al            ; possibly set it
  2604.         //        pop     es
  2605.         //    }
  2606. }
  2607.  
  2608.  
  2609.     /*\
  2610.     |*|----====< void SystemInit() >====----
  2611.     |*|
  2612.     |*| System wide initialization of the program
  2613.     |*|
  2614.     |*| Entry Conditions:
  2615.     |*|     None
  2616.     |*|
  2617.     |*| Exit Conditions:
  2618.     |*|     None
  2619.     |*|
  2620.     \*/
  2621. static int SystemInit()
  2622. {
  2623. int n;
  2624. long l;
  2625.  
  2626.     /* setup the mouse & move to the middle of the wave window          */
  2627.  
  2628.     //    MouseInit    (ON,OFF);
  2629.     //    MouseAction (0x12);             // left button down/up action
  2630.  
  2631.         if (_videocard() == 1) {        // if mono, point to that segment
  2632.             VideoSegment = OurWnd.sseg = 0xb000;
  2633.             Colors = &MonoScheme;
  2634.         }
  2635.  
  2636.     // get the original row, column and kill numlock
  2637.  
  2638.  
  2639.         l = _videogetcurs();
  2640.         OrigCol = (int) (l >> 16) & 0xffff;
  2641.         OrigRow = (int) l & 0xffff;
  2642.  
  2643.         _dlgsavenumlock();        // the below code is now in dialoga.asm
  2644.         //    _asm {
  2645.         //        push    es                            ; save the numlock state
  2646.         //        sub     ax,ax
  2647.         //        mov     es,ax
  2648.         //        mov     al,0x20
  2649.         //        and     al,es:[0x417]
  2650.         //        and     byte ptr es:[0x417],0xdf    ; clear it...
  2651.         //        mov     NumLockState,al
  2652.         //        pop     es
  2653.         //    }
  2654.  
  2655.     // turn off the cursor
  2656.  
  2657.         _videocshape (0,0x20);            // make it invisible
  2658.  
  2659.     /* init all objects, then paint them on the screen                    */
  2660.  
  2661.         BroadcastMsg (OPENINIT);        // tell everyone we are starting
  2662.  
  2663.         PaintScreen  (TRUE,FALSE);        // put up the screen
  2664.  
  2665.         BroadcastToList (DRAWIT,CurrList);// draw the controls
  2666.  
  2667.         (*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
  2668.  
  2669.     // return good
  2670.  
  2671.         return (0);
  2672. }
  2673.  
  2674.  
  2675.     /*\
  2676.     |*|----====< int VolumeButtons() >====----
  2677.     |*|
  2678.     |*| Volume slide bar object control
  2679.     |*|
  2680.     |*| Entry Conditions:
  2681.     |*|     None
  2682.     |*|
  2683.     |*| Exit Conditions:
  2684.     |*|     None
  2685.     |*|
  2686.     \*/
  2687. static int VolumeButtons (msg,o,ptr)
  2688.     int msg;
  2689.     BPtr o;
  2690.     void *ptr;
  2691. {
  2692. void **pptr;
  2693. rect r;
  2694. int l,ri,i;
  2695. char c1,c2;
  2696.  
  2697.     // get a pointer to the stack
  2698.  
  2699.         pptr = &ptr;
  2700.  
  2701.     // process the message
  2702.  
  2703.         switch (msg) {
  2704.  
  2705.             case OPEVENT:
  2706.  
  2707.                 switch (((EPtr)pptr[0])->buttons) {
  2708.  
  2709.                     case ENTER:
  2710.  
  2711.                         if (o->state)
  2712.                             o->state = 0;
  2713.                         else
  2714.                             o->state = -1;
  2715.  
  2716.                         SendVolume
  2717.                           (
  2718.                             "SET ",
  2719.                             0,
  2720.                             (VPtr) o,
  2721.                             BI_SETTO,
  2722.                             o->state
  2723.                           );
  2724.  
  2725.                         (*o->scr) (DRAWIT,o);
  2726.  
  2727.                         break;
  2728.  
  2729.                     case ENDKEY:
  2730.                     case HOMEKEY:
  2731.                     case LFARROW:
  2732.                     case PGDNKEY:
  2733.                     case PGUPKEY:
  2734.                     case RIARROW:
  2735.  
  2736.                         // Direction keys can move these sliders
  2737.  
  2738.                         if (o == &Loudness)
  2739.                             (*BassVolume.scr)(msg,&BassVolume,ptr);
  2740.  
  2741.                         if (o == &Enhanced)
  2742.                             (*TrebVolume.scr)(msg,&TrebVolume,ptr);
  2743.                         break;
  2744.  
  2745.                     default:
  2746.                         break;
  2747.                 }
  2748.  
  2749.                 break;
  2750.  
  2751.             case SENDIT:
  2752.  
  2753.                 SendVolume
  2754.                   (
  2755.                     "SET ",
  2756.                     0,
  2757.                     (VPtr) o,
  2758.                     BI_SETTO,
  2759.                     o->state
  2760.                   );
  2761.                 (*(void(*)())ptr)(&CommandString);
  2762.  
  2763.                 break;
  2764.  
  2765.             case FOCUS_GIVEN:
  2766.  
  2767.                 // highlight the entire field
  2768.  
  2769.                     r.row1 = o->namr.row1;
  2770.                     r.row2 = o->namr.row2;
  2771.                     r.col2 = r.col1 = o->namr.col2+2;
  2772.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  2773.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  2774.  
  2775.                 //    r.row1 = o->scrr.row1;
  2776.                 //    r.row2 = o->scrr.row2;
  2777.                 //    r.col2 = r.col1 = o->scrr.col2+2;
  2778.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  2779.                 //    _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  2780.  
  2781.                     break;
  2782.  
  2783.             case FOCUS_TAKEN:
  2784.  
  2785.                 // highlight the entire field
  2786.  
  2787.                     r.row1 = o->namr.row1;
  2788.                     r.row2 = o->namr.row2;
  2789.                     r.col2 = r.col1 = o->namr.col2+2;
  2790.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  2791.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  2792.  
  2793.                 //    r.row1 = o->scrr.row1;
  2794.                 //    r.row2 = o->scrr.row2;
  2795.                 //    r.col2 = r.col1 = o->scrr.col2+2;
  2796.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  2797.                 //    _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  2798.  
  2799.                     break;
  2800.  
  2801.             case DRAWIT:
  2802.  
  2803.                 // move the cursor to the slide bar area
  2804.  
  2805.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  2806.                     if (o->state)
  2807.                         _zipout   ( "X" );
  2808.                     else
  2809.                         _zipout   ( "∙" );
  2810.  
  2811.                 break;
  2812.  
  2813.             case OPENINIT:
  2814.  
  2815.                 // get the output mixer current state
  2816.  
  2817.                     SendVolume ("GET ",0,(VPtr)o,0,0);
  2818.  
  2819.                     DecodeVolumeSwitch (MVResponse);
  2820.                     o->state = (VolumeSwitch == '+') ? -1 : 0;
  2821.                     break;
  2822.  
  2823.  
  2824.             case CLEARIT:
  2825.             default:
  2826.                 break;
  2827.         }
  2828. }
  2829.  
  2830.  
  2831.     /*\
  2832.     |*|----====< int UpdateTotalVolume() >====----
  2833.     |*|
  2834.     |*| update the screen if the user is typing the hot keys
  2835.     |*|
  2836.     |*| Entry Conditions:
  2837.     |*|     None
  2838.     |*|
  2839.     |*| Exit Conditions:
  2840.     |*|     None
  2841.     |*|
  2842.     \*/
  2843. static int UpdateTotalVolume()
  2844. {
  2845. int lv,rv;
  2846.  
  2847. static int delta;
  2848. static int mintic    = 18;
  2849. static int minrest    = 0;
  2850. //static int lasttime = 0;
  2851.  
  2852.     // get the clock tic, this whole routine is done once a second
  2853.  
  2854.         delta += _dlggettimedelta();    // the below code is now in dialoga.asm
  2855.         //    _asm {
  2856.         //        mov ah,0
  2857.         //        int 1Ah
  2858.         //        cmp lasttime,dx     ; ax = delta of current/last time
  2859.         //        mov lasttime,dx
  2860.         //        adc delta,0
  2861.         //    }
  2862.  
  2863.     // if the main dialog box is covered, we cannot draw, so just return
  2864.  
  2865.         if (DialogBox & EFFECTS_DLG)
  2866.             return(0);
  2867.  
  2868.     // if the change is greater than 1 second, update the screen now...
  2869.  
  2870.         if (delta > mintic) {
  2871.  
  2872.             delta    = 0;
  2873.  
  2874.             lv = LeftVolumeLevel.channel;
  2875.             rv = RitVolumeLevel.channel;
  2876.  
  2877.             (*LeftVolumeLevel.scr)(OPENINIT,&LeftVolumeLevel);
  2878.  
  2879.             if((lv != LeftVolumeLevel.channel) ||
  2880.                (rv != RitVolumeLevel.channel)) {
  2881.                     minrest = (1*19)/4;         // restore speed after 1 second
  2882.                     mintic    = 2;                // speed up polling
  2883.                     (*LeftVolumeLevel.scr)(DRAWIT,&LeftVolumeLevel);
  2884.             }
  2885.  
  2886.             if (minrest)                        // if fast poll
  2887.                 if (!--minrest)                 // check to see if we should
  2888.                     mintic = 18;                // slow it down.
  2889.         }
  2890. }
  2891.  
  2892.  
  2893.     /*\
  2894.     |*|----====< int VolumeLevels() >====----
  2895.     |*|
  2896.     |*| VOLUME LEFT/RIGHT control
  2897.     |*|
  2898.     |*| Entry Conditions:
  2899.     |*|     None
  2900.     |*|
  2901.     |*| Exit Conditions:
  2902.     |*|     None
  2903.     |*|
  2904.     \*/
  2905. static int VolumeLevels(msg,o,ptr)
  2906.     int msg;
  2907.     VPtr o;
  2908.     void *ptr;
  2909. {
  2910. void **pptr;
  2911. rect r;
  2912. int l,ri,i;
  2913. char c1,c2;
  2914.  
  2915. #define VOLE_RAMPUP 0x4001        // ramp the volume up
  2916. #define VOLE_RAMPDN 0x4002        // ramp the volume down
  2917.  
  2918.     // get a pointer to the stack
  2919.  
  2920.         pptr = &ptr;
  2921.  
  2922.     // process the message
  2923.  
  2924.         switch (msg) {
  2925.  
  2926.             case OPEVENT:
  2927.  
  2928.                 switch (((EPtr)pptr[0])->buttons) {
  2929.  
  2930.                     case ENDKEY:
  2931.                         VolumeLevels (VOLE_RAMPUP,&RitVolumeLevel,ptr);
  2932.                         break;
  2933.  
  2934.                     case HOMEKEY:
  2935.                         VolumeLevels (VOLE_RAMPUP,&LeftVolumeLevel,ptr);
  2936.                         break;
  2937.  
  2938.                     case LFARROW:
  2939.                         VolumeLevels (VOLE_RAMPUP,&LeftVolumeLevel,ptr);
  2940.                         VolumeLevels (VOLE_RAMPUP,&RitVolumeLevel,ptr);
  2941.                         break;
  2942.  
  2943.                     case PGDNKEY:
  2944.                         VolumeLevels (VOLE_RAMPDN,&RitVolumeLevel,ptr);
  2945.                         break;
  2946.  
  2947.                     case PGUPKEY:
  2948.                         VolumeLevels (VOLE_RAMPDN,&LeftVolumeLevel,ptr);
  2949.                         break;
  2950.  
  2951.                     case RIARROW:
  2952.                         VolumeLevels (VOLE_RAMPDN,&LeftVolumeLevel,ptr);
  2953.                         VolumeLevels (VOLE_RAMPDN,&RitVolumeLevel,ptr);
  2954.                         break;
  2955.  
  2956.                     default:
  2957.                         break;
  2958.                 }
  2959.  
  2960.                 break;
  2961.  
  2962.             case SENDIT:
  2963.  
  2964.                 SendVolume                    // set the left
  2965.                   (
  2966.                     "SET ",
  2967.                     1,
  2968.                     &LeftVolumeLevel,
  2969.                     BI_SETTO,
  2970.                     LeftVolumeLevel.channel
  2971.                   );
  2972.                 (*(void(*)())ptr)(&CommandString);
  2973.  
  2974.                 SendVolume                    // set the right
  2975.                   (
  2976.                     "SET ",
  2977.                     2,
  2978.                     &RitVolumeLevel,
  2979.                     BI_SETTO,
  2980.                     RitVolumeLevel.channel
  2981.                   );
  2982.  
  2983.                 (*(void(*)())ptr)(&CommandString);
  2984.  
  2985.                 break;
  2986.  
  2987.             case FOCUS_GIVEN:
  2988.  
  2989.                 // highlight the entire field
  2990.  
  2991.                     r.row1 = o->namr.row1;
  2992.                     r.row2 = o->namr.row2;
  2993.                     r.col2 = r.col1 = o->namr.col2+2;
  2994.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  2995.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  2996.  
  2997.                     r.row1 = o->scrr.row1;
  2998.                     r.row2 = o->scrr.row2;
  2999.                     r.col2 = r.col1 = o->scrr.col2+2;
  3000.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  3001.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  3002.  
  3003.                 // let the right channel know too!
  3004.  
  3005.                     if (o == &LeftVolumeLevel)
  3006.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3007.  
  3008.                     break;
  3009.  
  3010.             case FOCUS_TAKEN:
  3011.  
  3012.                 // highlight the entire field
  3013.  
  3014.                     r.row1 = o->namr.row1;
  3015.                     r.row2 = o->namr.row2;
  3016.                     r.col2 = r.col1 = o->namr.col2+2;
  3017.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  3018.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  3019.  
  3020.                     r.row1 = o->scrr.row1;
  3021.                     r.row2 = o->scrr.row2;
  3022.                     r.col2 = r.col1 = o->scrr.col2+2;
  3023.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  3024.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  3025.  
  3026.                 // let the right channel know too!
  3027.  
  3028.                     if (o == &LeftVolumeLevel)
  3029.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3030.  
  3031.                     break;
  3032.  
  3033.             case DRAWIT:
  3034.  
  3035.                 // move the cursor to the slide bar area
  3036.  
  3037.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  3038.                     _zipout       ( twobar, 0);
  3039.  
  3040.                     l = (o->channel * 31) / 100;
  3041.                     _videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
  3042.                     _zipout (((l & 1) ? "▐" : "▌"), 0);
  3043.  
  3044.                 // let the right channel know too!
  3045.  
  3046.                     if (o == &LeftVolumeLevel)
  3047.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3048.  
  3049.                 break;
  3050.  
  3051.             case OPENINIT:
  3052.  
  3053.                 // get the output mixer current state
  3054.  
  3055.                     SendVolume
  3056.                       (
  3057.                         "GET ",
  3058.                         ((o == &LeftVolumeLevel) ? 1 : 2),
  3059.                         o,
  3060.                         0,
  3061.                         0
  3062.                       );
  3063.  
  3064.                     DecodeVolumeNumber (MVResponse);
  3065.                     o->channel = VolumeNumber;
  3066.  
  3067.                 // let the right channel know too!
  3068.  
  3069.                     if (o == &LeftVolumeLevel)
  3070.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3071.  
  3072.                     break;
  3073.  
  3074.             case CLEARIT:
  3075.                 break;
  3076.  
  3077.             case VOLE_RAMPUP:
  3078.  
  3079.                 // send the volume up
  3080.  
  3081.                     if (o->channel > 0)
  3082.                         o->channel -= 4;
  3083.  
  3084.                     SendVolume                    // set left/both/right
  3085.                       (
  3086.                         "SET ",
  3087.                         ((o == &LeftVolumeLevel) ? 1 : 2),
  3088.                         o,
  3089.                         BI_SETTO,
  3090.                         o->channel
  3091.                     );
  3092.  
  3093.                     (*o->scr) (DRAWIT,o);        // redraw it
  3094.  
  3095.                     break;
  3096.  
  3097.             case VOLE_RAMPDN:
  3098.  
  3099.                 // send the volume down
  3100.  
  3101.                     if (o->channel < 100)
  3102.                         o->channel += 4;
  3103.  
  3104.                     SendVolume
  3105.                       (
  3106.                         "SET ",
  3107.                         ((o == &LeftVolumeLevel) ? 1 : 2),
  3108.                         o,
  3109.                         BI_SETTO,
  3110.                         o->channel
  3111.                       );
  3112.  
  3113.                     (*o->scr) (DRAWIT,o);
  3114.  
  3115.                     break;
  3116.  
  3117.             default:
  3118.                 break;
  3119.         }
  3120. }
  3121.  
  3122.  
  3123. ;    /*\
  3124. ;---|*|----====< clrbuf() >====----
  3125. ;---|*|
  3126. ;---|*| zero out a buffer
  3127. ;---|*|
  3128. ;    \*/
  3129.  
  3130. clrbuf(char *buf, int size)
  3131. {
  3132.     int s;
  3133.  
  3134.     for (s= 0; s < size; s++)
  3135.         *buf++= '\0';
  3136. }
  3137.  
  3138.  
  3139. ;    /*\
  3140. ;---|*|----====< dissolve() >====----
  3141. ;---|*|
  3142. ;---|*| Take a buffer, and write it to the screen in a random fashion
  3143. ;---|*|
  3144. ;    \*/
  3145.  
  3146. dissolve(h,width,buff)
  3147.     int h;
  3148.     int width;
  3149.     char far *buff;
  3150. {
  3151. int pixels,lastnum;
  3152. int regwidth;
  3153. long mask;
  3154. unsigned long seq;
  3155. int row, col;
  3156.  
  3157.     // find the smallest "register" that produces enough pixel numbers
  3158.  
  3159.     pixels     = h * width;
  3160.  
  3161.     lastnum  = pixels -1;
  3162.  
  3163.     mask = 0x500;
  3164.  
  3165.     seq = 1;
  3166.  
  3167.     do {
  3168.  
  3169.         row = seq / width;
  3170.  
  3171.         col = seq % width;
  3172.  
  3173.         if (row < h)
  3174.             plug (row,col,buff);
  3175.  
  3176.         // compute the next element
  3177.  
  3178.         if (seq & 1) {
  3179.  
  3180.             _asm {
  3181.                 mov     ax,word ptr [seq]
  3182.                 shr     ax,1
  3183.                 xor     ax,word ptr [mask]
  3184.                 mov     word ptr [seq],ax
  3185.             }
  3186.  
  3187.             //seq = (seq >> 1) ~ mask;
  3188.         }
  3189.  
  3190.         else
  3191.  
  3192.             seq >>= 1;
  3193.  
  3194.     } while (seq != 1);
  3195.  
  3196.     plug (0,0,buff);
  3197. }
  3198.  
  3199.  
  3200. plug(row,col,buff)
  3201.     int row;
  3202.     int col;
  3203.     char far *buff;
  3204. {
  3205.  
  3206.     _asm {
  3207.  
  3208.         push    es
  3209.         push    si
  3210.  
  3211.         mov     ax,[row]
  3212.         mov     si,160
  3213.         mul     si
  3214.         add     ax,[col]
  3215.         add     ax,[col]
  3216.         mov     si,ax
  3217.  
  3218.         les     bx,[buff]
  3219.         mov     ax,es:[bx+si]
  3220.  
  3221.         mov     bx,0b800h
  3222.         mov     es,bx
  3223.         mov     es:[si],ax
  3224.  
  3225.         mov     dx,250h
  3226.         mov     cx,40h
  3227.  
  3228.     } xyz: _asm {
  3229.  
  3230.         in      al,dx
  3231.         loop    xyz
  3232.  
  3233.         pop     es
  3234.     }
  3235. }
  3236.  
  3237.  
  3238.  
  3239. /* filename is catted onto driver pathname, and the "s." is changed to "#." */
  3240. /* where "#" is from 0 to 3, allowing 4 different mixer settings to be saved. */
  3241.  
  3242. char *filename= "settings.pas";
  3243.  
  3244. /* miscellaneous words used with mvproas */
  3245.  
  3246. #define WORD_GET 0
  3247. #define WORD_MIXER 1
  3248. #define WORD_TO 2
  3249. #define WORD_ON 3
  3250. #define WORD_OFF 4
  3251. #define WORD_LEVEL 5
  3252. #define WORD_PERCENT 6
  3253.  
  3254. char *words[]=     {"GET ", "MIXER ", "TO ", "ON ", "OFF ", "LEVEL ", " PERCENT ", ""};
  3255.  
  3256. /* these words are used to retrieve/save the mixer settings */
  3257.  
  3258. char *direct[]=     {"INPUT ",     "OUTPUT ",     ""};
  3259. char *output[]=     {"PCM ",     "MIXER "};
  3260. char *channel[]=     {"LEFT ",     "RIGHT ",     ""};
  3261. char *source[]=     {"FM ",         "INT ", "EXT ", "SPEAKER ", "MIC ", "" };
  3262. char *levels[]=     {"BASS ",     "TREBLE ",     "ENHANCED ", ""};
  3263. char *buttons[]=     {"REALSOUND ", ""};
  3264. char *crossch[]=     {"CROSSCHANNEL ", ""};
  3265. char *volume[]=     {"VOLUME ", ""};
  3266. char *onoff[]=     {"-", "+", ""};
  3267.  
  3268. /* getdriverpath() - use int 2F function BC0B to get path to mvsound.sys */
  3269. /* return !0 and fill "pathname" buffer with path to driver if successful */
  3270. /* return 0 if failed */
  3271.  
  3272. getdriverpath(char far *pathname)
  3273. {
  3274.     int status;
  3275.     char far *p= pathname;
  3276.  
  3277.     _asm {
  3278.         mov ax, 0BC0Bh
  3279.         int 2Fh
  3280.  
  3281.         xor ax, 'M' SHL 8 + 'V'
  3282.         mov status, ax
  3283.         jnz sorry
  3284.  
  3285.         push ds
  3286.         push es
  3287.         push si
  3288.         push di
  3289.  
  3290.         mov di, word ptr p[2]
  3291.         mov es, di
  3292.         mov di, word ptr p[0]
  3293.         mov ds, dx
  3294.         mov si, bx
  3295.  
  3296.         mov cx, 79
  3297.  
  3298.     } again: _asm {
  3299.  
  3300.         lodsb
  3301.         stosb
  3302.         or al, al
  3303.         jz done
  3304.         loop again
  3305.  
  3306.         jmp short done
  3307.  
  3308.     } done: _asm {
  3309.  
  3310.         sub cx, 77
  3311.         jnz notroot
  3312.         mov bx,-1
  3313.         mov byte ptr es:[di], 0
  3314.         dec di
  3315.         mov byte ptr es:[di], 05ch
  3316.  
  3317.     } notroot: _asm {
  3318.  
  3319.         pop di
  3320.         pop si
  3321.         pop es
  3322.         pop ds
  3323.  
  3324.     } sorry:
  3325.  
  3326.     return(!status);
  3327. }
  3328.  
  3329. /* evaluate the "##   +/-   ##   +/-" string */
  3330. /* the first "## +/-" pair is the left channel, the second is the right */
  3331. /* set up four pointers to point to each of the four elements */
  3332. /* passed in is "channel", either 'L' or 'R', and "onoroff", either "+" or "-" */
  3333. /* if the L/R "onoroff" matches the passed "onoroff", return the L/R val */
  3334.  
  3335. char *isonoroff(char channel, char onoroff)
  3336. {
  3337.     char *lfvalue, *lfonoff, *rtvalue, *rtonoff;
  3338.     char *val, *oo;
  3339.  
  3340.     /* MVResponse= "LeftVal   LeftOnOff   RightVal   RightOnOff" */
  3341.     lfvalue= MVResponse;
  3342.     while (isspace(*lfvalue)) lfvalue++;
  3343.  
  3344.     lfonoff= lfvalue;
  3345.     while (!isspace(*lfonoff)) lfonoff++;
  3346.     while (isspace(*lfonoff)) lfonoff++;
  3347.  
  3348.     rtvalue= lfonoff;
  3349.     while (!isspace(*rtvalue)) rtvalue++;
  3350.     while (isspace(*rtvalue)) rtvalue++;
  3351.  
  3352.     rtonoff= rtvalue;
  3353.     while (!isspace(*rtonoff)) rtonoff++;
  3354.     while (isspace(*rtonoff)) rtonoff++;
  3355.  
  3356.     /* select val and oo according to Left or Right channel */
  3357.     switch (channel)
  3358.         {
  3359.         case 'l':
  3360.         case 'L': val= lfvalue; oo= lfonoff; break;
  3361.         case 'r':
  3362.         case 'R': val= rtvalue; oo= rtonoff; break;
  3363.         default: val= NULL; oo= NULL; break;
  3364.         }
  3365.  
  3366.     if (*oo == onoroff)
  3367.         return(val);
  3368.  
  3369.     return(NULL);
  3370.  
  3371. }
  3372.  
  3373. /* put an ascii number for "num" into the character left of the "." */
  3374. /* from the end of the string, search backwards to the first "." */
  3375. /* if not at the start of the string, stuff the ascii number */
  3376.  
  3377. putnuminname(char *pathname, int num)
  3378. {
  3379.     int i= strlen(pathname);
  3380.     while (i && pathname[i] != '.')
  3381.         i--;
  3382.     if (i)
  3383.         pathname[--i]= num+ '0';
  3384. }
  3385.  
  3386. /* get the driver path, stuff the number into the name, and create the file */
  3387. /* save the master L/R volume, the "dead" then the "live" mixer settings */
  3388. /* the bass, treble and enhanced status, the realsound setting, and the */
  3389. /* crosschannel settings */
  3390. /* These are saved as strings in a DOS file suitable for "cat FILE > mvproas" */
  3391. /* which is what the "loadcurrent()" function does */
  3392. /* The filename is "X:\driver\path\setting#.pas", where "#" is 0-3, allowing */
  3393. /* four different settings to be maintained */
  3394.  
  3395. #define USEMIXERGET 1
  3396.  
  3397. FILE *fout;
  3398.  
  3399. subsavecurrent(char *cmdstring)
  3400. {
  3401.     if (*cmdstring)
  3402.         {
  3403.         fprintf(fout, "%s\n", cmdstring);
  3404.         }
  3405.  
  3406.     return(0);
  3407. }
  3408.  
  3409. savecurrent(int num)
  3410. {
  3411.     char pathname[128];
  3412.  
  3413.     if (!getdriverpath(pathname))
  3414.         return(0);
  3415.  
  3416.     if (strlen(pathname) > 3)
  3417.         strcat(pathname, "\\");
  3418.     strcat(pathname, filename);
  3419.     putnuminname(pathname, num);
  3420.  
  3421.     fout= fopen(pathname, "w");
  3422.     if (fout == NULL)
  3423.           return(0);
  3424.  
  3425.     MixerGetSettings(subsavecurrent);
  3426.  
  3427.     fclose(fout);
  3428.  
  3429.     return(0);
  3430. }
  3431.  
  3432. /* load setting #num from file "setting#.pas" */
  3433. /* open the file, read each line and send it to mvproas */
  3434. /* if the file does not exist, save the current settings and then proceed */
  3435. /* The file contains mvproas strings, so "cat setting#.pas > mvproas" works */
  3436.  
  3437. loadcurrent(int num)
  3438. {
  3439.     int okay;
  3440.     FILE *finp;
  3441.     char pathname[128];
  3442.     char cmdstring[128];
  3443.  
  3444.     if (!getdriverpath(pathname))
  3445.         return(0);
  3446.  
  3447.     if (strlen(pathname) > 3)
  3448.         strcat(pathname, "\\");
  3449.     strcat(pathname, filename);
  3450.     putnuminname(pathname, num);
  3451.  
  3452.     finp= fopen(pathname, "r");
  3453.     if (finp == NULL)
  3454.         {
  3455.         savecurrent(num);
  3456.         finp= fopen(pathname, "r");
  3457.         if (finp == NULL)
  3458.             return(0);
  3459.         }
  3460.  
  3461.     while ((fgets(cmdstring, 127, finp)) != NULL)
  3462.         SendTextOut(cmdstring);
  3463.  
  3464.     fclose(finp);
  3465.  
  3466. }
  3467.  
  3468. /*The GET commands and parameters are:
  3469.        GET {LEFT or RIGHT} [FM     ]
  3470.        GET {LEFT or RIGHT} [PCM    ]
  3471.        GET {LEFT or RIGHT} [INT    ]
  3472.        GET {LEFT or RIGHT} [EXT    ]
  3473.        GET {LEFT or RIGHT} [SPEAKER]
  3474.        GET {LEFT or RIGHT} [MIC    ]
  3475.        GET [BASS]                   
  3476.        GET [TREBLE]                 
  3477.        GET {LEFT or RIGHT} [VOLUME ]
  3478.        GET [MUTE]
  3479.        GET [ENHANCED]
  3480.        GET [REALSOUND]
  3481.        GET [CROSSCHANNEL]
  3482. The following demonstrates several ways to GET volume, button, or mixer levels:
  3483.        GET FM
  3484.        GET VOLUME
  3485.        GET MUTE
  3486.        GET CROSSCHANNEL
  3487.        GET REAL
  3488. */
  3489.  
  3490. unlinkTBScroll()
  3491. {
  3492.     Scroll *n= (Scroll *) TBScroll.next;
  3493.     Scroll *b= (Scroll *) TBScroll.back;
  3494.  
  3495.     n->back= b;
  3496.     b->next= n;
  3497.  
  3498.     screen3[15]= screen3blank[0];
  3499.     screen3[16]= screen3blank[1];
  3500.     screen3[17]= screen3blank[2];
  3501.  
  3502.     screenlayout[17]= screenlayoutblank[0];
  3503.     screenlayout[18]= screenlayoutblank[1];
  3504.     screenlayout[19]= screenlayoutblank[2];
  3505.  
  3506.     screenlayout[15][2]= 'P';
  3507.     screenlayout[15][3]= 'C';
  3508.     screenlayout[15][4]= ' ';
  3509.     screenlayout[15][5]= 'S';
  3510.     screenlayout[15][6]= 'p';
  3511.     screenlayout[15][7]= 'e';
  3512.     screenlayout[15][8]= 'a';
  3513.     screenlayout[15][9]= 'k';
  3514.     screenlayout[15][10]='e';
  3515.     screenlayout[15][11]='r';
  3516.  
  3517.     screenlayout[16][2]= 'S';
  3518.     screenlayout[16][3]= 'B';
  3519.     screenlayout[16][4]= ' ';
  3520.     screenlayout[16][5]= 'V';
  3521.     screenlayout[16][6]= 'o';
  3522.     screenlayout[16][7]= 'l';
  3523.     screenlayout[16][8]= 'u';
  3524.     screenlayout[16][9]= 'm';
  3525.     screenlayout[16][10]='e';
  3526.     screenlayout[16][11]=' ';
  3527.  
  3528.  
  3529. }
  3530.  
  3531. ;    /*\
  3532. ;---|*| end DIALOG.C
  3533. ;    \*/
  3534.  
  3535.  
  3536.